diff options
-rw-r--r-- | driver/main.c | 31 | ||||
-rw-r--r-- | driver/main.h | 20 | ||||
-rw-r--r-- | driver/platform.c | 81 | ||||
-rw-r--r-- | driver/platform.h | 41 | ||||
-rw-r--r-- | dts/am335x-boneblack-uboot.dts | 15 | ||||
-rw-r--r-- | readme.md | 2 |
6 files changed, 35 insertions, 155 deletions
diff --git a/driver/main.c b/driver/main.c index 92ff9aa..2097edd 100644 --- a/driver/main.c +++ b/driver/main.c @@ -1,13 +1,9 @@ -// #include <linux/cdev.h> #include <linux/init.h> -#include <linux/io.h> -#include <linux/module.h> -#include <linux/platform_device.h> +#include <linux/i2c.h> #include "main.h" #include "platform.h" -// struct cdev *cdev; struct device *dev; struct class *class; dev_t node = 0; // do not register /dev/lork @@ -30,30 +26,14 @@ static int mod_init(void) { } // create platform driver - err = platform_driver_register(&lork_driver); + err = i2c_add_driver(&lork_driver); if (err) goto free_platform_driver; - // create driver attribute under /sys/bus/platform/drivers/gpio-extern - err = driver_create_file(&lork_driver.driver, &drv_attr_int); - if (err) goto free_drv_attr_int; - - // create device attributes under /sys/class - err = device_create_file(dev, &dev_attr_int); - if (err) goto free_dev_attr_int; - err = device_create_file(dev, &dev_attr_str); - if (err) goto free_dev_attr_str; - printk("%s() OK\n", __PRETTY_FUNCTION__); return 0; -free_dev_attr_str: - device_remove_file(dev, &dev_attr_str); -free_dev_attr_int: - device_remove_file(dev, &dev_attr_int); -free_drv_attr_int: - driver_remove_file(&lork_driver.driver, &drv_attr_int); free_platform_driver: - platform_driver_unregister(&lork_driver); + i2c_del_driver(&lork_driver); free_device: device_destroy(class, node); free_class: @@ -63,10 +43,7 @@ free_class: } static void mod_exit(void) { - device_remove_file(dev, &dev_attr_str); - device_remove_file(dev, &dev_attr_int); - driver_remove_file(&lork_driver.driver, &drv_attr_int); - platform_driver_unregister(&lork_driver); + i2c_del_driver(&lork_driver); device_destroy(class, node); class_destroy(class); printk("%s()\n", __PRETTY_FUNCTION__); diff --git a/driver/main.h b/driver/main.h index a0ef924..666bcc1 100644 --- a/driver/main.h +++ b/driver/main.h @@ -5,18 +5,26 @@ #include "platform.h" -static const struct of_device_id lork_ids[] = { - { .compatible = "gpio-extern" }, +static const struct of_device_id lork_match[] = { + { .compatible = "lork-i2c" }, {}, }; -struct platform_driver lork_driver = { +static const struct i2c_device_id lork_ids[] = { + { "foo", 0 }, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, lork_ids); + +struct i2c_driver lork_driver = { .probe = lork_probe, .remove = lork_remove, .driver = { - .name = "gpio-extern", + .name = "lork", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(lork_ids), - } + .of_match_table = of_match_ptr(lork_match), + }, + .id_table = lork_ids, }; diff --git a/driver/platform.c b/driver/platform.c index b177474..db82d14 100644 --- a/driver/platform.c +++ b/driver/platform.c @@ -1,85 +1,14 @@ #include "platform.h" +#include <linux/platform_device.h> #include <linux/types.h> -#include <linux/of.h> -#include <linux/of_address.h> -// TODO: shouldn't these be used?? -// #include <linux/pinctrl/pinctrl.h> -// #include <linux/gpio/driver.h> - -#include <dt-bindings/gpio/gpio.h> - -// NOTE: i believe any nonzero return value for the probe function is -// recognized as an error because of -// <https://github.com/torvalds/linux/blob/a5131c3fdf2608f1c15f3809e201cf540eb28489/drivers/base/platform.c#L1004> -int lork_probe(struct platform_device* dev) { - // read gpios field from device tree - uint32_t dt_gpios[3]; - of_property_read_u32_array(dev->dev.of_node, "gpios", dt_gpios, 3); - - struct device_node* gpio1 = of_find_node_by_phandle(dt_gpios[0]); - uint32_t pin = dt_gpios[1]; - uint32_t gpio_mode = dt_gpios[2]; - printk("lork: configure pin %u w/ mode 0x%02x\n", pin, gpio_mode); - - // find the multiplexer that controls pin - size_t len = of_property_count_u32_elems(gpio1, "gpio-ranges"); - struct device_node* am33xx_pinmux = NULL; - for (size_t i = 0; i < len; i += 4) { - uint32_t phandle, pin_start, pin_offset, pin_size; - of_property_read_u32_index(gpio1, "gpio-ranges", i+0, &phandle); - of_property_read_u32_index(gpio1, "gpio-ranges", i+1, &pin_start); - of_property_read_u32_index(gpio1, "gpio-ranges", i+2, &pin_offset); - of_property_read_u32_index(gpio1, "gpio-ranges", i+3, &pin_size); - - // get phandle for multiplexer corresponding to configured pin number - if (pin_start > pin || pin >= pin_start + pin_size) continue; - - am33xx_pinmux = of_find_node_by_phandle(phandle); - printk("0x%02x, %u -> %u + %u\n", phandle, pin_start, pin_offset, pin_size); - break; - } - if (am33xx_pinmux == NULL) return EINVAL; - - printk("%s(%s)\n", __PRETTY_FUNCTION__, dev->name); +int lork_probe(struct i2c_client * client) { + printk(KERN_INFO "%s()\n", __PRETTY_FUNCTION__); return 0; } -int lork_remove(struct platform_device* dev) { - printk("%s(%s)\n", __PRETTY_FUNCTION__, dev->name); - return 0; -} - -unsigned int val = 0; -ssize_t drv_attr_int_show(struct device_driver* drv, char* buf) { - return sprintf(buf, "%u\n", val); -} -ssize_t drv_attr_int_store(struct device_driver* drv, const char* buf, size_t count) { - sscanf(buf, "%u", &val); - return count; -} - -ssize_t dev_attr_int_show(struct device* dev, struct device_attribute* _attr, char* buf) { - return sprintf(buf, "%u\n", val); -} -ssize_t dev_attr_int_store(struct device* dev, struct device_attribute* _attr, const char* buf, size_t count) { - sscanf(buf, "%u", &val); - return count; -} - -char* str = NULL; -size_t str_len = 0; -ssize_t dev_attr_str_show(struct device* dev, struct device_attribute* _attr, char* buf) { - if (str == NULL) return 0; - strncpy(buf, str, str_len); - return str_len; -} -ssize_t dev_attr_str_store(struct device* dev, struct device_attribute* _attr, const char* buf, size_t count) { - if (str != NULL) kfree(str); - str = kmalloc(count, 0); - str_len = count; - strncpy(str, buf, str_len); - return count; +void lork_remove(struct i2c_client * client) { + return; } diff --git a/driver/platform.h b/driver/platform.h index ecac681..1173c3a 100644 --- a/driver/platform.h +++ b/driver/platform.h @@ -1,43 +1,8 @@ #pragma once -#include <linux/types.h> #include <linux/platform_device.h> -#include <linux/slab.h> +#include <linux/i2c.h> -int lork_probe(struct platform_device*); -int lork_remove(struct platform_device*); - - -ssize_t drv_attr_int_show(struct device_driver*, char*); -ssize_t drv_attr_int_store(struct device_driver*, const char*, size_t); -static const struct driver_attribute drv_attr_int = { - .attr = { - .name = "int", - .mode = 0644, - }, - .show = drv_attr_int_show, - .store = drv_attr_int_store, -}; - -ssize_t dev_attr_int_show(struct device*, struct device_attribute*, char*); -ssize_t dev_attr_int_store(struct device*, struct device_attribute*, const char*, size_t); -static const struct device_attribute dev_attr_int = { - .attr = { - .name = "int", - .mode = 0644, - }, - .show = dev_attr_int_show, - .store = dev_attr_int_store, -}; - -ssize_t dev_attr_str_show(struct device*, struct device_attribute*, char*); -ssize_t dev_attr_str_store(struct device*, struct device_attribute*, const char*, size_t); -static const struct device_attribute dev_attr_str = { - .attr = { - .name = "str", - .mode = 0644, - }, - .show = dev_attr_str_show, - .store = dev_attr_str_store, -}; +int lork_probe(struct i2c_client *); +void lork_remove(struct i2c_client *); diff --git a/dts/am335x-boneblack-uboot.dts b/dts/am335x-boneblack-uboot.dts index 43c1cfe..9cdeada 100644 --- a/dts/am335x-boneblack-uboot.dts +++ b/dts/am335x-boneblack-uboot.dts @@ -2177,7 +2177,7 @@ #size-cells = <0x01>; ranges = <0x00 0x9c000 0x1000>; - i2c@0 { + i2c2: i2c@0 { compatible = "ti,omap4-i2c"; #address-cells = <0x01>; #size-cells = <0x00>; @@ -2241,6 +2241,12 @@ phandle = <0xbb>; }; }; + + // NOTE: this is in i2c2, so I2C2_SCL = P9.19 and I2C2_SDA = P9.20 + lork { + compatible = "lork-i2c"; // load my driver + addr = <0x22>; // i2c slave address (see ../arduino/main.cpp) + }; }; }; @@ -3892,11 +3898,4 @@ not_available = "/not_available"; vmmcsd_fixed = "/fixedregulator0"; }; - - // this section is visible at runtime under - // /sys/firmware/devicetree/base/lork - lork { - compatible = "gpio-extern"; - gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>; - }; }; @@ -15,6 +15,7 @@ - [Driver API][driver-api] - [AM335x Technical reference manual][ti-am335x-rm] - [BeagleBone Black system reference manual][bbb-srm] +- [I2C device driver guide][linux-i2c] [kbuild-obj-var]: https://docs.kernel.org/kbuild/makefiles.html#loadable-module-goals-obj-m [kbuild-module-makefile]: https://www.kernel.org/doc/html/latest/kbuild/modules.html#creating-a-kbuild-file-for-an-external-module @@ -25,6 +26,7 @@ [driver-api]: https://www.kernel.org/doc/html/latest/driver-api/infrastructure.html [ti-am335x-rm]: https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf [bbb-srm]: https://cdn-shop.adafruit.com/datasheets/BBB_SRM.pdf +[linux-i2c]: https://www.kernel.org/doc/html/latest/i2c/writing-clients.html # tips |