raspberry pi - I2C linux driver can't find device -


i have written little i2c driver testing purposes.

i using rasperry pi 3 , have connected 2 ssd1306 oled displays i2c pins on gpio pin header. able connect it, using i2c-tools using adresses 0x3c , 0x3d.

i able send data displays using i2c-set:

i2cset -y 1 0x3c [data] i2cset -y 1 0x3d [data] 

the command

i2cdetect -y 1 

gives me following output:

     0  1  2  3  4  5  6  7  8  9   b  c  d  e  f 00:          -- -- -- -- -- -- -- -- -- -- -- -- --  10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  30: -- -- -- -- -- -- -- -- -- -- -- -- 3c 3d -- --  40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  70: -- -- -- -- -- -- -- --                         

i using following driver see , how i2c in linux may work:

#include "i2c_test.h"  #include <linux/module.h> #include <linux/init.h> #include <linux/version.h> #include <linux/types.h>  #include <linux/i2c.h> #include <linux/mod_devicetable.h>  #define print_client(c) printk("%s: client (name: %s), (flags: %x), (addr: %x), (adapter: ), (device: ), (irq: %d)\n",\                                 __function__, c->name, c->flags, c->addr, c->irq) #define print_board(b) printk("%s: board (type: %s), (flags: %x), (addr: %x), (irq: %d)\n",\                                 __function__, b->type, (unsigned int)b->flags, (unsigned int)b->addr, b->irq)  static struct i2c_device_id ssd1306_idtable[] = {     { "ssd1306", 0 },     {} };  const unsigned short ssd1306_address_list[] = {     0x3c,     0x3d,     0x7a,     0x78, };   module_device_table(i2c, ssd1306_idtable);  struct dev_pm_ops ssd1306_pm_ops = { // don't know how use };  #if linux_version_code < kernel_version(4,10,0) int ssd1306_probe(struct i2c_client* client, const struct i2c_device_id * dev_id) {     print_client(client);     return 0; } #else //linux_version_code > kernel_version(4,10,0) int ssd1306_probe_new(struct i2c_client* client) {     print_client(client);     return 0; } #endif // kernel version  int ssd1306_remove(struct i2c_client* client) {     print_client(client);     return 0; }  void ssd1306_shutdown(struct i2c_client* client) {     print_client(client); }  int ssd1306_detect(struct i2c_client* client, struct i2c_board_info* board_info) {     print_client(client);     print_board(board_info);     return 0; }  static struct i2c_driver ssd1306_driver = {     .driver = {         .name   = "i2c_test",         .pm = &ssd1306_pm_ops     },      .id_table   = ssd1306_idtable, #if linux_version_code < kernel_version(4,10,0)     .probe      = ssd1306_probe, #else //linux_version_code > kernel_version(4,10,0)     .probe_new = ssd1306_probe_new, //needs kernel 4.10 or later #endif //kernel version     .remove     = ssd1306_remove,     .class      = i2c_class_hwmon, // correct??     .detect     = ssd1306_detect,     .address_list   = ssd1306_address_list,      //.command  = ssd1306_command,     .shutdown   = ssd1306_shutdown };   static int __init mod_init(void) {     printk("init " __file__ "\n");     i2c_add_driver(&ssd1306_driver);     printk("driver added!\n");     return 0; }  static void __exit mod_exit(void) {     printk("remove driver\n");     i2c_del_driver(&ssd1306_driver);     printk("driver removed\n");     printk("exit " __file__ "\n"); }  module_init( mod_init ); module_exit( mod_exit );  module_license("gpl"); 

i following output dmesg:

[ 1676.649683] init /home/pi/projects/playground/i2c_test/i2c_test.c [ 1676.649790] driver added! [ 1812.043182] remove driver [ 1812.043301] driver removed [ 1812.043306] exit /home/pi/projects/playground/i2c_test/i2c_test.c 

it nice if know or doing wrong , me.

thanks

p0kr

i2c devices not probed automatically when module loaded (i2c not offer standard method this). so, have driver's probe function called, need tell kernel i2c addr should handled driver. simple method using sysfs is:

# echo [your_device_name] [your_device_i2c_addr] > /sys/bus/i2c/devices/i2c-[i2c_bus_number]/new_device 

(replace parts in square brackets appropriate numbers , names)

in particular case be

 # echo ssd1306 0x3c > /sys/bus/i2c/devices/i2c-1/new_device 

note kernel won't checking you, probe function called regardless i2c device connected or not.

other methods include, example, specifying device , driver in device tree data. more details refer linux kernel documentation.

edit: in situation autodetection exists (and detect function called), i2c bus has agree on (and device class have match, among others). method not used general devices far know, rather internal monitoring sensors in pc etc. specifying device explicitly preferred method in situations.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -