#include#include #include #include #define ZCC210_I2C_ADDRESS 0x60 #define ZCC210_DIRECTION_COMMAND 0X77 #define ZCC210_DRIVER_NAME "zcc210" /* Addresses to scan */ static const unsigned short normal_i2c[] = {ZCC210_I2C_ADDRESS, I2C_CLIENT_END}; /*Device interface functions*/ static s32 zcc210_read_direction(struct i2c_client *client) { /* Read direction bytes*/ return i2c_smbus_read_word_data(client, ZCC210_DIRECTION_COMMAND); } /*sysfs callback functions*/ static ssize_t show_values(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); s32 result = zcc210_read_direction(client); if(result > 0){ return sprintf(buf, "%d\n", (s32)swab32((u32)result)); } return result; } static DEVICE_ATTR(values, S_IRUGO, show_values, NULL); //static struct i2c_board_info zcc210_i2c_board_info = { // I2C_BOARD_INFO(ZCC210_DRIVER_NAME, ZCC210_I2C_ADDRESS), // }; static struct attribute *zcc210_attributes[] = { &dev_attr_values.attr, NULL }; static const struct attribute_group zcc210_attr_group = { .attrs = zcc210_attributes, }; static const struct i2c_device_id zcc210_id[] = { { ZCC210_DRIVER_NAME, 0}, {} }; static int zcc210_detect(struct i2c_client *client, struct i2c_board_info *info) { if (client->addr != ZCC210_I2C_ADDRESS) return -ENODEV; strlcpy(info->type, ZCC210_DRIVER_NAME, I2C_NAME_SIZE); return 0; } static int zcc210_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err; printk(KERN_INFO "%s: new instance found!\n", ZCC210_DRIVER_NAME); /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &zcc210_attr_group); if (err) { return err; } return 0; } static int zcc210_remove(struct i2c_client *client) { sysfs_remove_group(&client->dev.kobj, &zcc210_attr_group); return 0; } static struct i2c_driver zcc210_driver ={ .driver.name = ZCC210_DRIVER_NAME, .id_table = zcc210_id, .probe = zcc210_probe, .remove = zcc210_remove, .class = I2C_CLASS_HWMON, .detect = zcc210_detect, .address_list = normal_i2c, }; static int __init zcc210_init(void) { printk(KERN_INFO "%s: init!", ZCC210_DRIVER_NAME ); return i2c_add_driver(&zcc210_driver); } static void __exit zcc210_exit(void) { printk(KERN_INFO "%s: exit!", ZCC210_DRIVER_NAME ); i2c_del_driver(&zcc210_driver); } MODULE_AUTHOR("Karthik S Prakash <karthik.s.prakash@yahoo.com"); MODULE_DESCRIPTION("Zhichuan ZCC210 I2C Compass driver"); MODULE_LICENSE("GPL"); module_init(zcc210_init); module_exit(zcc210_exit);
Sunday, April 15, 2012
Before I go to bed, I want to share a linux device driver I wrote sometime back for an old Zichuan ZCC210N I2C compass. Unfortunately, it stopped working before I could test the driver. I don't have the tools to debug the module, but the driver compiles and loads fine. Since, this was one of the early compass modules available in hobby stores, I thought someone out there might find this code useful.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment