From patchwork Tue Nov 17 10:07:36 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "A. Porodko" X-Patchwork-Id: 60609 Received: from comal.ext.ti.com (comal.ext.ti.com [198.47.26.152]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nAHA9KUn003659 for ; Tue, 17 Nov 2009 10:09:21 GMT Received: from dlep36.itg.ti.com ([157.170.170.91]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id nAHA7qRi001079 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 17 Nov 2009 04:07:52 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep36.itg.ti.com (8.13.8/8.13.8) with ESMTP id nAHA7pm5015387; Tue, 17 Nov 2009 04:07:51 -0600 (CST) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 306C780627; Tue, 17 Nov 2009 04:07:51 -0600 (CST) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp53.itg.ti.com (dflp53.itg.ti.com [128.247.5.6]) by linux.omap.com (Postfix) with ESMTP id 518F980626 for ; Tue, 17 Nov 2009 04:07:48 -0600 (CST) Received: from medina.ext.ti.com (localhost [127.0.0.1]) by dflp53.itg.ti.com (8.13.8/8.13.8) with ESMTP id nAHA7mbZ005717 for ; Tue, 17 Nov 2009 04:07:48 -0600 (CST) Received: from mail10-tx2-R.bigfish.com (mail-tx2.bigfish.com [65.55.88.111]) by medina.ext.ti.com (8.13.7/8.13.7) with ESMTP id nAHA7lP3023741 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Tue, 17 Nov 2009 04:07:48 -0600 Received: from mail10-tx2 (localhost.localdomain [127.0.0.1]) by mail10-tx2-R.bigfish.com (Postfix) with ESMTP id C1D74CF0345 for ; Tue, 17 Nov 2009 10:07:47 +0000 (UTC) X-SpamScore: 3 X-BigFish: vps3(z3c23mz655Nzz1202h1082kzz5a6ciz2fh6bh63h) X-Spam-TCS-SCL: 2:0 X-MS-Exchange-Organization-Antispam-Report: OrigIP: 83.142.161.14; Service: EHS Received: from mail10-tx2 (localhost.localdomain [127.0.0.1]) by mail10-tx2 (MessageSwitch) id 1258452460880097_23684; Tue, 17 Nov 2009 10:07:40 +0000 (UTC) Received: from TX2EHSMHS007.bigfish.com (unknown [10.9.14.254]) by mail10-tx2.bigfish.com (Postfix) with ESMTP id BC1672F8056 for ; Tue, 17 Nov 2009 10:07:40 +0000 (UTC) Received: from relay.intersvyaz.net (83.142.161.14) by TX2EHSMHS007.bigfish.com (10.9.99.107) with Microsoft SMTP Server id 14.0.482.32; Tue, 17 Nov 2009 10:07:39 +0000 Received: from localhost (unknown [10.100.10.115]) by relay.intersvyaz.net (Postfix) with ESMTP id BCB4280A83B; Tue, 17 Nov 2009 15:07:37 +0500 (YEKT) Received: from relay.intersvyaz.net ([10.100.10.225]) by localhost (relay.intersvyaz.net [10.100.10.115]) (amavisd-new, port 10024) with ESMTP id Xh86b-b+vxlf; Tue, 17 Nov 2009 15:07:37 +0500 (YEKT) Received: from localhost.localdomain (pool-78-29-57-200.is74.ru [78.29.57.200]) by relay.intersvyaz.net (Postfix) with ESMTP id 1D98F80A816; Tue, 17 Nov 2009 15:07:37 +0500 (YEKT) From: Andrey Porodko To: davinci-linux-open-source@linux.davincidsp.com Subject: [PATCH fixed] MSP430 chip support for Neuros OSD2 board. MSP430 provides RTC, IR remote, Date: Tue, 17 Nov 2009 15:07:36 +0500 Message-ID: <1258452456-15077-1-git-send-email-panda@chelcom.ru> X-Mailer: git-send-email 1.5.6.5 MIME-Version: 1.0 X-Reverse-DNS: mail.is74.ru Cc: Andrey Porodko X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com 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 + * + * 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 +#include +#include +#include + + +/* + * 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 + * + * 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 */