Andrey Porodko <pa...@chelcom.ru> writes:

> I must apologize, I missed some obvious style mistakes and again forgot to
> run checkpatch. Corrected.
>
> Signed-off-by: Andrey Porodko <pa...@chelcom.ru>

As suggested by Sekhar in the original review, I suggest you reuse the
existing MSP430 driver, factoring into common parts and board specific
parts where needed.  Yes, it's currently called dm355, but that's an easy
rename that can be done towards the end.

There is just too much shared code to have new driver for this board.

Kevin


> ---
>  arch/arm/mach-davinci/board-neuros-osd2.c |    3 +
>  drivers/mfd/Kconfig                       |    8 +
>  drivers/mfd/Makefile                      |    1 +
>  drivers/mfd/neuros_osd2_msp.c             |  204 
> +++++++++++++++++++++++++++++
>  include/linux/i2c/neuros_osd2_msp.h       |   43 ++++++
>  5 files changed, 259 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mfd/neuros_osd2_msp.c
>  create mode 100644 include/linux/i2c/neuros_osd2_msp.h
>
> diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c 
> b/arch/arm/mach-davinci/board-neuros-osd2.c
> index bd9ca07..0949fa9 100644
> --- a/arch/arm/mach-davinci/board-neuros-osd2.c
> +++ b/arch/arm/mach-davinci/board-neuros-osd2.c
> @@ -202,6 +202,9 @@ static struct davinci_i2c_platform_data ntosd2_i2c_pdata 
> = {
>  };
>  
>  static struct i2c_board_info __initdata ntosd2_i2c_info[] =  {
> +     {                                       /* MSP430 interface     */
> +             I2C_BOARD_INFO("neuros_osd2_msp", NTOSD2_MSP430_I2C_ADDR),
> +     },
>  };
>  
>  static       int ntosd2_init_i2c(void)
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 570be13..41ceebc 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -43,6 +43,14 @@ config MFD_DM355EVM_MSP
>         boards.  MSP430 firmware manages resets and power sequencing,
>         inputs from buttons and the IR remote, LEDs, an RTC, and more.
>  
> +config MFD_NEUROS_OSD2_MSP
> +     bool "Neuros OSD2 open set top box microcontroller"
> +     depends on I2C && MACH_NEUROS_OSD2
> +     help
> +       This driver supports the MSP430 microcontroller used on these
> +       boards.  MSP430 firmware manages inputs/outputs from IR remote,
> +       an RTC and more.
> +
>  config HTC_EGPIO
>       bool "HTC EGPIO support"
>       depends on GENERIC_HARDIRQS && GPIOLIB && ARM
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index f3b277b..32baa62 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -9,6 +9,7 @@ obj-$(CONFIG_HTC_EGPIO)               += htc-egpio.o
>  obj-$(CONFIG_HTC_PASIC3)     += htc-pasic3.o
>  
>  obj-$(CONFIG_MFD_DM355EVM_MSP)       += dm355evm_msp.o
> +obj-$(CONFIG_MFD_NEUROS_OSD2_MSP) += neuros_osd2_msp.o
>  
>  obj-$(CONFIG_MFD_T7L66XB)    += t7l66xb.o
>  obj-$(CONFIG_MFD_TC6387XB)   += tc6387xb.o
> diff --git a/drivers/mfd/neuros_osd2_msp.c b/drivers/mfd/neuros_osd2_msp.c
> new file mode 100644
> index 0000000..489ab63
> --- /dev/null
> +++ b/drivers/mfd/neuros_osd2_msp.c
> @@ -0,0 +1,204 @@
> +/*
> + * neuros_osd2_msp.c - driver for MSP430 firmware on Neuros OSD2 board
> + *
> + * Based on code of dm355evm_msp.c by David Brownell
> + * 2009 (c) 2009 Andrey A. Porodko <andrey.poro...@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#include <linux/platform_device.h>
> +#include <linux/err.h>
> +#include <linux/i2c.h>
> +#include <linux/i2c/neuros_osd2_msp.h>
> +
> +
> +/*
> + * Neuros OSD2 has an MSP430 programmed with firmware for various board
> + * support functions.
> + */
> +
> +#if defined(CONFIG_INPUT_NEUROS_OSD2) || \
> +                             defined(CONFIG_INPUT_NEUROS_OSD2_MODULE)
> +#define msp_has_keys()       true
> +#else
> +#define msp_has_keys()       false
> +#endif
> +
> +#if defined(CONFIG_RTC_DRV_NEUROS_OSD2) || \
> +                             defined(CONFIG_RTC_DRV_NEUROS_OSD2_MODULE)
> +#define msp_has_rtc()                true
> +#else
> +#define msp_has_rtc()                false
> +#endif
> +
> +#if defined(CONFIG_NEUROS_OSD2_IRBLASTER) || \
> +                             defined(CONFIG_NEUROS_OSD2_IRBLASTER_MODULE)
> +#define msp_has_irblaster()  true
> +#else
> +#define msp_has_irblaster()  false
> +#endif
> +
> +static struct i2c_client *msp430;
> +
> +/**
> + * ntosd2_msp_write_byte - Writes command with parameter in neuros_osd2_msp
> + * @value: the value to be written
> + * @reg: the register in MSP430
> + *
> + * Returns result of operation - 0 is success, else negative errno
> + */
> +int ntosd2_msp_write_byte(u8 reg, u8 value)
> +{
> +
> +     return i2c_smbus_write_byte_data(msp430, reg, value);
> +}
> +EXPORT_SYMBOL(ntosd2_msp_write_byte);
> +
> +/**
> + * ntosd2_msp_read_byte - Reads a byte from neuros_osd2_msp
> + * @reg: the reg in msp430
> + *
> + * Returns result of operation - byte read, or negative errno
> + */
> +int ntosd2_msp_read_byte(u8 reg)
> +{
> +
> +     return i2c_smbus_read_byte_data(msp430, reg);
> +}
> +EXPORT_SYMBOL(ntosd2_msp_read_byte);
> +
> +
> +/*----------------------------------------------------------------------*/
> +
> +static struct device *add_child(struct i2c_client *client, const char *name,
> +                             void *pdata, unsigned pdata_len,
> +                             bool can_wakeup, int irq)
> +{
> +     struct platform_device  *pdev;
> +     int                     status;
> +
> +     pdev = platform_device_alloc(name, -1);
> +     if (!pdev) {
> +             dev_dbg(&client->dev, "can't alloc dev\n");
> +             status = -ENOMEM;
> +             goto err;
> +     }
> +
> +     device_init_wakeup(&pdev->dev, can_wakeup);
> +     pdev->dev.parent = &client->dev;
> +
> +     if (pdata) {
> +             status = platform_device_add_data(pdev, pdata, pdata_len);
> +             if (status < 0) {
> +                     dev_dbg(&pdev->dev, "can't add platform_data\n");
> +                     goto err;
> +             }
> +     }
> +
> +     if (irq) {
> +             struct resource r = {
> +                     .start = irq,
> +                     .flags = IORESOURCE_IRQ,
> +             };
> +
> +             status = platform_device_add_resources(pdev, &r, 1);
> +             if (status < 0) {
> +                     dev_dbg(&pdev->dev, "can't add irq\n");
> +                     goto err;
> +             }
> +     }
> +     status = platform_device_add(pdev);
> +err:
> +     if (status < 0) {
> +             platform_device_put(pdev);
> +             dev_err(&client->dev, "can't add %s dev\n", name);
> +             return ERR_PTR(status);
> +     }
> +     return &pdev->dev;
> +}
> +
> +static int add_children(struct i2c_client *client)
> +{
> +     struct device   *child;
> +
> +     /* RTC */
> +     if (msp_has_rtc()) {
> +             child = add_child(client, "rtc_neuros_osd2",
> +                             NULL, 0, false, 0);
> +             if (IS_ERR(child))
> +                     return PTR_ERR(child);
> +     }
> +
> +     /* input from IR remote (uses the IRQ) */
> +     if (msp_has_keys()) {
> +             child = add_child(client, "neuros_osd2_ir",
> +                             NULL, 0, true, client->irq);
> +             if (IS_ERR(child))
> +                     return PTR_ERR(child);
> +     }
> +
> +     /* output to IR blaster  */
> +     if (msp_has_irblaster()) {
> +             child = add_child(client, "neuros_osd2_irblaster",
> +                             NULL, 0, true, client->irq);
> +             if (IS_ERR(child))
> +                     return PTR_ERR(child);
> +     }
> +     return 0;
> +}
> +
> +/*----------------------------------------------------------------------*/
> +
> +static int ntosd2_msp_remove(struct i2c_client *client)
> +{
> +     msp430 = NULL;
> +     return 0;
> +}
> +
> +static int ntosd2_msp_probe(struct i2c_client *client,
> +                             const struct i2c_device_id *id)
> +{
> +     int     status;
> +
> +     if (msp430) {
> +             status = -EBUSY;
> +     } else {
> +             msp430 = client;
> +     status = add_children(client);
> +     if (status >= 0)
> +             status = 0;
> +     }
> +     if (status < 0)                         /* failed...            */
> +             ntosd2_msp_remove(client);
> +     return status;
> +}
> +
> +static const struct i2c_device_id ntosd2_msp_ids[] = {
> +     { "neuros_osd2_msp", 0 },
> +     { /* end of list */ },
> +};
> +MODULE_DEVICE_TABLE(i2c, ntosd2_msp_ids);
> +
> +static struct i2c_driver ntosd2_msp_driver = {
> +     .driver.name    = "neuros_osd2_msp",
> +     .id_table       = ntosd2_msp_ids,
> +     .probe          = ntosd2_msp_probe,
> +     .remove         = ntosd2_msp_remove,
> +};
> +
> +static int __init ntosd2_msp_init(void)
> +{
> +     return i2c_add_driver(&ntosd2_msp_driver);
> +}
> +subsys_initcall(ntosd2_msp_init);
> +
> +static void __exit ntosd2_msp_exit(void)
> +{
> +     i2c_del_driver(&ntosd2_msp_driver);
> +}
> +module_exit(ntosd2_msp_exit);
> +
> +MODULE_DESCRIPTION("Interface to MSP430 firmware on Neuros OSD2");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/i2c/neuros_osd2_msp.h 
> b/include/linux/i2c/neuros_osd2_msp.h
> new file mode 100644
> index 0000000..3b428d1
> --- /dev/null
> +++ b/include/linux/i2c/neuros_osd2_msp.h
> @@ -0,0 +1,43 @@
> +/*
> + * neuros_osd2_msp.h - support MSP430 microcontroller on Neuros OSD2 board
> + * 2009 (c) Andrey A. Porodko <andrey.poro...@gmail.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +#ifndef __LINUX_I2C_NEUROS_OSD2_MSP
> +#define __LINUX_I2C_NEUROS_OSD2_MSP
> +
> +/* utilities to access "registers" emulated by msp430 firmware */
> +extern int ntosd2_msp_write_byte(u8 reg, u8 value);
> +extern int ntosd2_msp_read_byte(u8 reg);
> +
> +/* MSP commands (registers) */
> +#define      NTOSD2_MSP430_GETIRCODE   0xB0
> +#define      NTOSD2_MSP430_GETVER      0x36
> +#define NTOSD2_MSP430_RTC_MDAY         0x19
> +#define      NTOSD2_MSP430_RTC_MONTH   0x1A
> +#define      NTOSD2_MSP430_RTC_YEAR    0x1B /* year since 2006, 0 = 2006     
> */
> +#define      NTOSD2_MSP430_RTC_HOURS   0x18
> +#define      NTOSD2_MSP430_RTC_MINUTES 0x17
> +#define      NTOSD2_MSP430_RTC_SECONDS 0x16
> +
> +#define      NTOSD2_MSP430_READ_RETRIES 3
> +
> +#define      NTOSD2_MSP430_RESET       6    /* reset to MSP430 high - active 
> */
> +#define      NTOSD2_MSP430_IRR_IRQ     7    /* Raw data from IR sensor       
> */
> +#define      NTOSD2_MSP430_PWM0        45   /* out, generates 38 kHz for IR 
> Blaster*/
> +#define      NTOSD2_MSP430_ARM_BLSTR   47   /* Raw data to IR Blaster        
> */
> +
> +#define      NTOSD2_MSP430_MAX_PULSES  128  /* max pulses in buffer          
> */
> +#define      NTOSD2_MSP430_IO_TIMEOUT  75   /* default I/O timeout in ms     
> */
> +#define      NTOSD2_MSP430_POOLING_TIMEOUT 10000/* default sensor polling in 
> us */
> +
> +#define      NTOSD2_IR_BLASTER_IOC_MAGIC 'i'/* code for IR blaster ioctl     
> */
> +#define RRB_SET_IO_TIMEOUT     _IOW(NTOSD2_IR_BLASTER_IOC_MAGIC, \
> +                                     1, unsigned long)
> +#define RRB_SET_POOLING_TIMEOUT   _IOW(NTOSD2_IR_BLASTER_IOC_MAGIC, \
> +                                     2, unsigned long)
> +
> +#endif /* __LINUX_I2C_NEUROS_OSD2_MSP */
> -- 
> 1.5.6.5
>
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> Davinci-linux-open-source@linux.davincidsp.com
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to