Introduction to Android G Sensor I²C Driver on Android

21,669 views
21,344 views

Published on

Introduction to Android G Sensor i2c Driver on Android

Published in: Technology, Business
1 Comment
29 Likes
Statistics
Notes
  • android g sensor
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
21,669
On SlideShare
0
From Embeds
0
Number of Embeds
2,447
Actions
Shares
0
Downloads
0
Comments
1
Likes
29
Embeds 0
No embeds

No notes for slide

Introduction to Android G Sensor I²C Driver on Android

  1. 1. Introduction to Android G sensor I²C Driver on Android Bo-Yi Wu 2010.06.04 Gemtek Technology Co., Ltd
  2. 2. Outline <ul><li>What’s G sensor ? </li></ul><ul><li>I²C Driver </li></ul><ul><li>Kernel Patch </li></ul><ul><li>Issue </li></ul><ul><li>Reference </li></ul>
  3. 3. What’s G sensor & Application <ul><li>As accelerometers are more and more present in mobile devices, new features are developed. Portrait & Landscape is one of them. It allows devices to display the information in the right orientation depending on how it is held. </li></ul>
  4. 4. Orientation estimation
  5. 5. Orientation estimation
  6. 6. Stability check <ul><li>STABLE_THRES </li></ul><ul><li>STABLE_COUNT_MIN </li></ul><ul><ul><li>calling rate? bigger or smaller? </li></ul></ul>
  7. 7. Code Review
  8. 8. I²C : detection capability set i2c address value detect call back function detect address fill the structure i2c_board_info
  9. 9. New-style drivers vs Legacy drivers <ul><li>Legacy drivers duplicate a lot of code . </li></ul><ul><li>The code needed in each driver to implement a detect callback is way smaller than the code needed to implement a legacy driver. </li></ul>
  10. 10. New-style drivers: initial function <ul><li>module_init ( BMA150_init ); </li></ul><ul><ul><li>return i2c_add_driver (&bma150_driver); </li></ul></ul><ul><li>module_exit ( BMA150_exit ); </li></ul><ul><ul><li>i2c_del_driver (&bma150_driver); </li></ul></ul><ul><li>__exit && __init (Kernel built in or module) </li></ul>
  11. 11. G Sensor: bma150_driver structure <ul><li>New-style driver </li></ul>Legacy driver probe: Callback for device binding (new-style drivers) remove: Callback for device unbinding (new-style drivers) class : What kind of i2c device we instantiate (for detect) (1<<0) for sensor address_data: The I2C addresses to probe, ignore or force (for detect) id_table: List of I2C devices supported by this driver
  12. 12. Legacy driver: address_data
  13. 13. New-style drivers: address_data /* Internal numbers to terminate lists */ I2C_CLIENT_END : 0xfffeU I2C_CLIENT_INSMOD_1 ~ I2C_CLIENT_INSMOD_8 I2C_CLIENT_INSMOD_COMMON : define structure address_data normal_i2c, probe, ignore value
  14. 14. I2c Driver: i2c_register_driver 1. new style driver methods can't mix with legacy ones /* check bma150_driver is news style driver or not */ is_newstyle_driver (driver) 2. /* check bma150_driver is Legacy style driver or not */ driver->attach_adapter || driver->detach_adapter || driver->detach_client 4. /* add bma150 driver to list for i2c only */ INIT_LIST_HEAD (&driver->clients) 5. /* Walk the adapters that are already present */ class_for_each_device struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; 3. /* register driver with bus, and use bus_add_driver () to add bus driver */ driver_register (&driver->driver);
  15. 15. I2c Driver: __attach_adapter <ul><li>Call __attach_adapter function </li></ul><ul><ul><li>New style driver: </li></ul></ul><ul><ul><ul><li>i2c_detect (adapter, driver); </li></ul></ul></ul><ul><ul><li>Legacy driver: </li></ul></ul><ul><ul><ul><li>driver-> attach_adapter (adapter); </li></ul></ul></ul>/* Because Legacy driver don’t have detect function */ if (!driver-> detect || !address_data) return 0;
  16. 16. I2c Driver: i2c_detect <ul><li>/* initial i2c client structure */ </li></ul><ul><li>struct i2c_client *temp_client; temp_client->adapter = adapter; </li></ul><ul><li>/* get address from i2c_client_address_data*/ </li></ul><ul><ul><li>address_data = driver ->address_data; </li></ul></ul><ul><li>/* check if Legacy driver */ </li></ul><ul><ul><li>if (! driver ->detect || ! address_data ) </li></ul></ul><ul><li>/* check normal_i2c ignore probe address */ </li></ul><ul><li>for(i = 0; address_data ->normal_i2c[i] != I2C_CLIENT_END ; i += 1) </li></ul>
  17. 17. I2c Driver: i2c_detect_address <ul><li>/* Make sure the address is valid */ </li></ul><ul><li>( addr < 0x03 || addr > 0x77 ) </li></ul><ul><li>/* Make sure there is something at this address */ </li></ul><ul><li>i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK , NULL) </li></ul><ul><li>/* Finally call the custom detection function */ </li></ul><ul><li>memset(&info, 0, sizeof(struct i2c_board_info)); </li></ul><ul><li>driver-> detect (temp_client, kind, &info); </li></ul><ul><li>use info.type[0] == '‘ to check driver->detect function </li></ul><ul><li>/* Detection succeeded, instantiate the device */ </li></ul><ul><li>client = i2c_new_device (adapter, &info); </li></ul><ul><li>list_add_tail (&client->detected, &driver->clients); </li></ul>
  18. 18. I2c Driver: i2c_new_device <ul><li>Set i2c_client info from i2c_board_info structure </li></ul><ul><li>strlcpy (client->name, info->type, sizeof(client->name)); </li></ul><ul><li>client->addr = info->addr; </li></ul><ul><li>client->irq = info->irq; </li></ul><ul><li>……… .. </li></ul><ul><li> </li></ul>
  19. 19. I2c Driver: i2c_device_match <ul><li>I2c_bus_type is used on new-style driver </li></ul><ul><li>i2c_device_match </li></ul><ul><ul><li>match client i2c_device_id  table && i2c_client table id </li></ul></ul><ul><li>i2c_device_probe </li></ul><ul><ul><li>Call bma150_probe function if you defined driver’s probe. </li></ul></ul>
  20. 20. I2c Driver:bma150_probe <ul><li>/* bma150 device create ok if return 0*/ </li></ul><ul><li>misc_register (&bma_device); </li></ul><ul><li>/* initial data */ </li></ul><ul><li>data->smb380. bus_write = bma150_i2c_write; </li></ul><ul><li>data->smb380. bus_read = bma150_i2c_read; </li></ul><ul><li>data->smb380. delay_msec = bma150_i2c_delay; </li></ul><ul><li>data->smb380. dev_addr = client->addr; </li></ul><ul><li>smb380_init(&(data->smb380)); </li></ul>
  21. 21. I2c Driver: file_operations
  22. 22. Build Linux Kernel <ul><li>Edit Kconfig & Makefile </li></ul><ul><li>Patch all files(bma150_drivers.c…) </li></ul><ul><li>Make menuconfig </li></ul><ul><li>Make uImage </li></ul>
  23. 23. Issue: can’t create device <ul><li>/* Make sure there is something at this address */ </li></ul><ul><li>i2c_smbus_xfer (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK , NULL) </li></ul><ul><li>Please edit i2c_smbus_xfer_emulated function and </li></ul><ul><li>Change message data length: 0 -> 1 </li></ul>
  24. 24. Demo To Do: jni module
  25. 25. Reference <ul><li>Linux Device Drivers, Third Edition </li></ul>
  26. 26. <ul><li>Thank You. </li></ul>

×