I must apologize, I missed some obvious style mistakes and again forgot to
run checkpatch. Corrected.

Signed-off-by: Andrey Porodko <[email protected]>
---
 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 <[email protected]>
+ *
+ * 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 <[email protected]>
+ *
+ * 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
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to