External I2C integration on Beagle Bone Black

Hi Team

I am trying to get expertise on I2C device drivers
I am trying to interface an external EEPROM to my beagle bone

I am checking the default drivers that is present in drivers folder of Linux kernel
and trying to implement such and interface eeprom
I need support on how Linux client driver and hardware interfacing and software changes to be done

My initial driver code is as below

#include<linux/i2c.h>``` #include<linux/init.h> `#include<linux/module.h>
#include<linux/of.h>``` #include<linux/slab.h> `#include<linux/sysfs.h>
#include<linux/spinlock.h>``` #define MAX_SIZE 512 `#define SLICE_SIZE 16
#define EEPROM_SIZE 1024``` #define USER_EEPROM_SIZE 1024`struct` `eeprom_buffer{`char data[32]; ```struct mutex lock;
struct` `i2c_client *fake_client;` `};` `` `` `static` `ssize_t eeprom_read(``struct` `i2c_client *client , ``int` `slice)` `{` struct eeprom_buffer *buffer =i2c_get_clientdata(client); ```int i, j, addr;
char` `buf[32];` mutex_lock(&buffer->lock);`

```if``(i2c_smbus_write_byte_data(client,addr>>8,addr &0XFF))`
```{`
```goto` `exit``;`
```}`
``
```if``(i2c_check_functionality(client->adapter,I2C_FUNC_SMBUS_READ_I2C_BLOCK))`
```{`
```if``(i2c_smbus_read_i2c_block_data(client,MAX_SIZE,SLICE_SIZE,buf)!=SLICE_SIZE)`
```{`
```goto` `exit``;`
```}`
```}`
```else```
```{`
```for``(i=0;i<MAX_SIZE;i++)`
```{`
```j=i2c_smbus_read_byte(client);`
```}`
```buf[i]=j;`
```}`

exit``:` mutex_unlock(&buffer->lock); }``static ssize_t eeprom_read_wrapper(struct` `file *fp, struct kobject *kobj,struct` `bin_attribute *bin_attr, char *buf,loff_t off, size_t` `count)` `{` ```struct` `i2c_client *client =kobj_to_i2c_client(kobj);` ```struct` `eeprom_buffer *buffer= i2c_get_clientdata(client);` ```int` `slice ,max_slice;`
if``(off >EEPROM_SIZE)` return 0; ```eeprom_read(client,slice);
```memcpy(buf,&buffer->data[off],count); ```return count;
}
`static` `struct` `bin_attribute user_eeprom = {` ```.attr = {` ```.name =“eepromd” }, ```.size = USER_EEPROM_SIZE,
.read = eeprom_read_wrapper,` `};` `` `` `static` `int` `eeprom_probe(``struct` `i2c_client *client , ``const` `struct` `i2c_device_id *id)` `{` struct eeprom_buffer *buffer; ```int size = id->driver_data;
int` `ret;` `` buffer=devm_kzalloc(&client->dev,sizeof(struct` `eeprom_buffer)+size,GFP_KERNEL);` ```if(!buffer) ```return -ENOMEM;
i2c_set_clientdata(client,buffer);` `// ret=i2c_slave_register(client,i2c_slave_operations);
if``(ret)` { ```return ret;
}` ret = sysfs_create_bin_file(&client->dev.kobj,&user_eeprom); ```if``(ret)
goto` `exit_probe;` `` return 0; exit_probe: ```i2c_unregister_device(buffer->fake_client);
`}`
static int eeprom_remove(``struct i2c_client *client)
{
``
struct` `eeprom_buffer *buffer=i2c_get_clientdata(client);` i2c_unregister_device(buffer->fake_client);`

```sysfs_remove_bin_file(&client->dev.kobj,&user_eeprom);`
```return` `0;`
`}`
``
`static` `const` `struct` `i2c_device_id eeprom_table[] ={`
```{``"deepak_eeprom"``,0},`
```{ }`
`};`
`MODULE_DEVICE_TABLE(i2c,eeprom_table);`
``
`static` `struct` `i2c_driver eeprom_driver={`
```.driver = {`
```.name=``"eeprom"``,`
```.owner=THIS_MODULE,`
```},`
```.probe = eeprom_probe,`
```.``remove` `= eeprom_remove,`
```.id_table = eeprom_table,`

};
static int __init eeprom_init()
{
printk(``"adding eeporm driver\n"``);` return i2c_add_driver(&eeprom_driver); }``static void __exit eeprom_exit() { ```printk(``"removing eeprom driver\n"``);
```i2c_del_driver(&eeprom_driver); }`

Kindly help on development and changes to be done and how do I interface eeprom to My board

Thanks you
Deepak

Hi Team

Can you please help me on this

  1. How could I start this and interfacing EEPROM with my board

  2. Hardware and software support needed

  3. Pointers to check on this

4)Beagle bone booting with latest kernel version and bring up so that flexible to flash using emmc and recompile kernel and root file system DTB frequently

Thank you
Deepak R

It is not clear what you are trying to do.

Are you trying to learn about Linux kernel device drivers?

Or, are you trying to interface a specific EEPROM to your Beaglebone Black?

If you are trying to interface an I2C device to your BBB, then there is a universal low level I2C driver in the kernel that is accessible from userspace, and bus I2C-2 is already configured on the BBB.
You don’t have to touch the kernel, you don’t have to touch the default device tree in the standard Debian releases for the BBB.

You do have to pick a programming language, tool chain, etc and write the high level driver to talk to the device using the low level “universal I2C” functions.
Lots of sample code for various ARM processors and I2C parts out there.
But you can do all of this from userspace.

If your goal is to learn how to write Linux kernel drivers and recompile the kernel, and write device trees and compile them, for bus oriented communications subsystems, then you might need to read a book or take a university course on each of those topics.

If you want help, then you need to be much more specific as to what you want, and what you are trying to do.

Like which specific Beagle device you want to use.

Which I2C part are you trying to talk to?

What languages and tool chains are you familiar with?

— Graham

On Fri, 20 Apr 2018 08:35:17 -0700 (PDT), Graham
<graham@flex-radio.com> declaimed the following:

Like which specific Beagle device you want to use.

  Uhm -- the post SUBJECT line states BBB

What languages and tool chains are you familiar with?

  Judging by the quoted text, the OP appears to be using C (I'd suspect
the native GCC <G>)