diff --git a/driver/counter.c b/driver/counter.c index 4ed5d3e..ff2ea69 100644 --- a/driver/counter.c +++ b/driver/counter.c @@ -7,20 +7,24 @@ #include #include -/* Meta Information */ +#include "ls7366r.h" + + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Wolfgang Hottgenroth"); MODULE_DESCRIPTION("A simple LKM to parse the device tree for a specific device and its properties"); +/* leds stuff */ static int dt_leds_probe(struct platform_device *pdev); static void dt_leds_remove(struct platform_device *pdev); static struct of_device_id leds_driver_ids[] = { { .compatible = "hottis,leds", - }, { /* sentinel */ } + }, + {}, }; -// MODULE_DEVICE_TABLE(of, leds_driver_ids); +MODULE_DEVICE_TABLE(of, leds_driver_ids); static struct platform_driver leds_driver = { .probe = dt_leds_probe, @@ -31,48 +35,13 @@ static struct platform_driver leds_driver = { }, }; -/* -static int dt_ls7366r_probe(struct spi_device *client); -static void dt_ls7366r_remove(struct spi_device *client); - -static struct of_device_id ls7366r_driver_ids[] = { - { - .compatible = "hottis,ls7366r0", - }, {} -}; -MODULE_DEVICE_TABLE(of, ls7366r_driver_ids); - -static struct spi_device_id ls7366r[] = { - { "ls7366r0", 0 }, - {}, -}; -MODULE_DEVICE_TABLE(spi, ls7366r); - -static struct spi_driver ls7366r_driver = { - .probe = dt_ls7366r_probe, - .remove = dt_ls7366r_remove, - .id_table = ls7366r, - .driver = { - .name = "ls7366r0", - .of_match_table = ls7366r_driver_ids, - }, -}; -*/ - - - -/* GPIO variable */ static struct gpio_desc *red_led = NULL; static struct gpio_desc *blue_led = NULL; - -/** - * @brief This function is called on loading the driver - */ static int dt_leds_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - printk("counter - led probing\n"); + printk("counter - leds probing\n"); if(!device_property_present(dev, "red-led-gpio")) { printk("counter - Error! Device property 'red-led-gpio' not found!\n"); @@ -99,19 +68,95 @@ static int dt_leds_probe(struct platform_device *pdev) { return 0; } -/** - * @brief This function is called on unloading the driver - */ static void dt_leds_remove(struct platform_device *pdev) { - printk("counter - led removing\n"); + printk("counter - leds removing\n"); gpiod_put(red_led); gpiod_put(blue_led); } +/* spi stuff */ +static int dt_ls7366r_probe(struct spi_device *client); +static void dt_ls7366r_remove(struct spi_device *client); + +/* LS7366R functions */ +static int writeCmd(struct spi_device *client, u8 c) { + u8 buf[1]; + buf[0] = c; + return spi_write(client, buf, 1); +} + +static int writeCmdData(struct spi_device *client, u8 c, u8 d) { + u8 buf[2]; + buf[0] = c; + buf[1] = d; + return spi_write(client, buf, 2); +} + +static int read32(struct spi_device *client, u8 c, u32 *r) { + u8 tx_buf[5]; + tx_buf[0] = c; + u8 rx_buf[5]; + struct spi_transfer t = { + .tx_buf = tx_buf, + .rx_buf = rx_buf, + .len = 5, + }; + int ret = spi_sync_transfer(client, &t, 1); + if (ret < 0) { + printk("counter - Error! spi_sync_transfer failed in read32\n"); + return ret; + } + printk("counter - Info! rx_buf: %02x %02x %02x %02x %02x\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3], rx_buf[4]); + *r = ((u32)rx_buf[1] << 24) | ((u32)rx_buf[2] << 16) | ((u32)rx_buf[3] << 8) | ((u32)rx_buf[4]); + return 0; +} + +static int read8(struct spi_device *client, u8 c, u8 *r) { + u8 tx_buf[2]; + tx_buf[0] = c; + u8 rx_buf[2]; + struct spi_transfer t = { + .tx_buf = tx_buf, + .rx_buf = rx_buf, + .len = 2, + }; + int ret = spi_sync_transfer(client, &t, 1); + if (ret < 0) { + printk("counter - Error! spi_sync_transfer failed in read8\n"); + return ret; + } + printk("counter - Info! rx_buf: %02x %02x\n", rx_buf[0], rx_buf[1]); + *r = rx_buf[1]; + return 0; +} -/* + + +static struct of_device_id ls7366r_driver_ids[] = { + { + .compatible = "hottis,ls7366r", + }, {} +}; +MODULE_DEVICE_TABLE(of, ls7366r_driver_ids); + +static struct spi_device_id ls7366r[] = { + { "ls7366r", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(spi, ls7366r); + +static struct spi_driver ls7366r_driver = { + .probe = dt_ls7366r_probe, + .remove = dt_ls7366r_remove, + .id_table = ls7366r, + .driver = { + .name = "ls7366r_device_driver", + .of_match_table = ls7366r_driver_ids, + }, +}; + static int dt_ls7366r_probe(struct spi_device *client) { printk("counter - ls7366r probing\n"); @@ -121,33 +166,60 @@ static int dt_ls7366r_probe(struct spi_device *client) { return ret; } + ret = writeCmd(client, CMD_CLR | REG_STR); + if (ret < 0) { + printk("counter - Error! writeCmd 1 failed in probe\n"); + return ret; + } + ret = writeCmd(client, CMD_CLR | REG_CNTR); + if (ret < 0) { + printk("counter - Error! writeCmd 2 failed in probe\n"); + return ret; + } + ret = writeCmdData(client, CMD_WR | REG_MDR0, MDR0_ILO); + if (ret < 0) { + printk("counter - Error! writeCmdData failed in probe\n"); + return ret; + } + + u8 x; + ret = read8(client, CMD_RD | REG_MDR0, &x); + if (ret < 0) { + printk("counter - Error! read8 failed in probe\n"); + return ret; + } + printk("counter - Info! x = %02x\n", x); + + u32 y; + ret = read32(client, CMD_RD | REG_OTR, &y); + if (ret < 0) { + printk("counter - Error! read32 failed in probe\n"); + return ret; + } + printk("counter - Info! y = %d\n", y); + + return 0; } - static void dt_ls7366r_remove(struct spi_device *client) { printk("counter - ls7366r removing\n"); } -*/ -/** - * @brief This function is called, when the module is loaded into the kernel - */ +/* module loading and unloading */ static int __init my_init(void) { - printk("counter - Loading the drivers...\n"); - - if (platform_driver_register(&leds_driver)) { - printk("counter - Error! Could not load leds driver\n"); + printk("counter - Loading the leds driver...\n"); + if(platform_driver_register(&leds_driver)) { + printk("dt_gpio - Error! Could not load driver\n"); return -1; } - /* + printk("counter - Loading the ls7366r driver...\n"); if (spi_register_driver(&ls7366r_driver)) { printk("counter - Error! Could not load spi driver\n"); return -1; } - */ printk("counter - red led on\n"); gpiod_set_value(red_led, 1); @@ -155,19 +227,15 @@ static int __init my_init(void) { return 0; } -/** - * @brief This function is called, when the module is removed from the kernel - */ static void __exit my_exit(void) { - printk("counter - Unload drivers"); - printk("counter - red led off\n"); gpiod_set_value(red_led, 0); + printk("counter - Unloading the leds driver...\n"); platform_driver_unregister(&leds_driver); - /* + + printk("counter - Unloading the ls7366r driver...\n"); spi_unregister_driver(&ls7366r_driver); - */ } module_init(my_init); diff --git a/driver/counter.dts b/driver/counter.dts index 43c1922..289f687 100644 --- a/driver/counter.dts +++ b/driver/counter.dts @@ -3,7 +3,7 @@ / { compatible = "brcm,bcm2835"; fragment@0 { - target-path = "/"; + target-path = "/soc"; __overlay__ { status = "okay"; leds { @@ -14,7 +14,6 @@ }; }; - /* fragment@1 { target = <&spidev0>; __overlay__ { @@ -29,8 +28,8 @@ #address-cells = <1>; #size-cells = <0>; - ls7366r: ls7366r0@0 { - compatible = "hottis,counter"; + ls7366r: ls7366r@0 { + compatible = "hottis,ls7366r"; reg = <0x0>; spi-max-frequency = <1000000>; spi-bits-per-word = <8>; @@ -38,6 +37,5 @@ }; }; }; - */ }; diff --git a/driver/ls7366r.h b/driver/ls7366r.h new file mode 100644 index 0000000..3388dba --- /dev/null +++ b/driver/ls7366r.h @@ -0,0 +1,53 @@ +#ifndef _LS7366R_H_ +#define _LS7366R_H_ + +#define REG_MDR0 0b00001000 +#define REG_MDR1 0b00010000 +#define REG_DTR 0b00011000 +#define REG_CNTR 0b00100000 +#define REG_OTR 0b00101000 +#define REG_STR 0b00110000 + +#define CMD_CLR 0b00000000 +#define CMD_RD 0b01000000 +#define CMD_WR 0b10000000 +#define CMD_LOAD 0b11000000 + +#define STR_CY 0b10000000 +#define STR_BW 0b01000000 +#define STR_CMP 0b00100000 +#define STR_IDX 0b00010000 +#define STR_CEN 0b00001000 +#define STR_PLS 0b00000100 +#define STR_UD 0b00000010 +#define STR_S 0b00000001 + +#define MDR0_NOQ 0b00000000 +#define MDR0_Q1 0b00000001 +#define MDR0_Q2 0b00000010 +#define MDR0_Q4 0b00000011 +#define MDR0_FRC 0b00000000 +#define MDR0_SCC 0b00000100 +#define MDR0_RLC 0b00001000 +#define MDR0_MNC 0b00001100 +#define MDR0_DI 0b00000000 +#define MDR0_ILC 0b00010000 +#define MDR0_IRC 0b00100000 +#define MDR0_ILO 0b00110000 +#define MDR0_AI 0b00000000 +#define MDR0_SI 0b01000000 +#define MDR0_FC1 0b00000000 +#define MDR0_FC2 0b10000000 + +#define MDR1_4CM 0b00000000 +#define MDR1_3CM 0b00000001 +#define MDR1_2CM 0b00000010 +#define MDR1_1CM 0b00000011 +#define MDR1_EC 0b00000000 +#define MDR1_DC 0b00000100 +#define MDR1_F_IDX 0b00010000 +#define MDR1_F_CMP 0b00100000 +#define MDR1_F_BW 0b01000000 +#define MDR1_F_CY 0b10000000 + +#endif /* _LS7366R_H_ */