diff options
author | Andrea Adami <andrea.adami@gmail.com> | 2016-01-12 22:34:17 +0100 |
---|---|---|
committer | Andrea Adami <andrea.adami@gmail.com> | 2016-01-19 22:44:01 +0100 |
commit | d9edb47c98812d9617e5132b32202f5463ec0796 (patch) | |
tree | 3bb5ca3a94d6d4fc8f10acc6465fa07b2d824c55 /recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch | |
parent | 1dc06f845b2ac531f64d3154ea6280f9243fc865 (diff) | |
download | meta-handheld-krogoth.tar.gz |
linux-yocto_3.14: remove stale recipekrogoth
Kernel 3.14 and 3.19 have been removed from oe-core with commit
6814521d0b88ee66442158ed70e77cbdd35d4782
Signed-off-by: Andrea Adami <andrea.adami@gmail.com>
Diffstat (limited to 'recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch')
-rw-r--r-- | recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch | 712 |
1 files changed, 0 insertions, 712 deletions
diff --git a/recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch b/recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch deleted file mode 100644 index 2470cdf..0000000 --- a/recipes-kernel/linux/linux-yocto-3.14/h3600/0001-MFD-driver-for-Atmel-Microcontroller-on-iPaq-h3xxx.patch +++ /dev/null @@ -1,712 +0,0 @@ -From a2073bd47b86b1ad3ba0600e772cd0f14ba73838 Mon Sep 17 00:00:00 2001 -From: Linus Walleij <linus.walleij@linaro.org> -Date: Fri, 31 Jan 2014 14:34:35 +0100 -Subject: [PATCH 1/7] MFD: driver for Atmel Microcontroller on iPaq h3xxx - -This adds a driver for the Atmel Microcontroller found on the -iPAQ h3xxx series. This device handles some keys, the -touchscreen, and the battery monitoring. - -This is a port of a driver from handhelds.org 2.6.21 kernel, -written by Alessandro Gardich based on Andrew Christians -original HAL-driver. It has been heavily cleaned and -converted to mfd-core by Dmitry Artamonow and rewritten -again for the v3.x series kernels by Linus Walleij, -bringing back some of the functionality lost from Andrew's -original driver. - -Cc: Russell King <linux@arm.linux.org.uk> -Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> -Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Signed-off-by: Alessandro Gardich <gremlin@gremlin.it> -Signed-off-by: Dmitry Artamonow <mad_soft@inbox.ru> -Signed-off-by: Linus Walleij <linus.walleij@linaro.org> ---- - drivers/mfd/Kconfig | 10 + - drivers/mfd/Makefile | 1 + - drivers/mfd/ipaq-micro.c | 487 +++++++++++++++++++++++++++++++++++++++++ - include/linux/mfd/ipaq-micro.h | 148 +++++++++++++ - 4 files changed, 646 insertions(+) - create mode 100644 drivers/mfd/ipaq-micro.c - create mode 100644 include/linux/mfd/ipaq-micro.h - -diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig -index 49bb445d846a..255807afc582 100644 ---- a/drivers/mfd/Kconfig -+++ b/drivers/mfd/Kconfig -@@ -242,6 +242,16 @@ config MFD_INTEL_MSIC - Passage) chip. This chip embeds audio, battery, GPIO, etc. - devices used in Intel Medfield platforms. - -+config MFD_IPAQ_MICRO -+ bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" -+ depends on SA1100_H3100 || SA1100_H3600 -+ select MFD_CORE -+ help -+ Select this to get support for the Microcontroller found in -+ the Compaq iPAQ handheld computers. This is an Atmel -+ AT90LS8535 microcontroller flashed with a special iPAQ -+ firmware using the custom protocol implemented in this driver. -+ - config MFD_JANZ_CMODIO - tristate "Janz CMOD-IO PCI MODULbus Carrier Board" - select MFD_CORE -diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile -index 5aea5ef0a62f..cf8081fcb3ac 100644 ---- a/drivers/mfd/Makefile -+++ b/drivers/mfd/Makefile -@@ -166,3 +166,4 @@ obj-$(CONFIG_MFD_RETU) += retu-mfd.o - obj-$(CONFIG_MFD_AS3711) += as3711.o - obj-$(CONFIG_MFD_AS3722) += as3722.o - obj-$(CONFIG_MFD_STW481X) += stw481x.o -+obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o -diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c -new file mode 100644 -index 000000000000..f71dffdd3f0f ---- /dev/null -+++ b/drivers/mfd/ipaq-micro.c -@@ -0,0 +1,487 @@ -+/* -+ * Compaq iPAQ h3xxx Atmel microcontroller companion support -+ * -+ * This is an Atmel AT90LS8535 with a special flashed-in firmware that -+ * implements the special protocol used by this driver. -+ * -+ * based on previous kernel 2.4 version by Andrew Christian -+ * Author : Alessandro Gardich <gremlin@gremlin.it> -+ * Author : Dmitry Artamonow <mad_soft@inbox.ru> -+ * Author : Linus Walleij <linus.walleij@linaro.org> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/pm.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/platform_device.h> -+#include <linux/io.h> -+#include <linux/mfd/core.h> -+#include <linux/mfd/ipaq-micro.h> -+#include <linux/string.h> -+#include <linux/random.h> -+#include <linux/slab.h> -+#include <linux/list.h> -+ -+#include <mach/hardware.h> -+ -+static void ipaq_micro_trigger_tx(struct ipaq_micro *micro) -+{ -+ struct ipaq_micro_txdev *tx = µ->tx; -+ struct ipaq_micro_msg *msg = micro->msg; -+ int i, bp; -+ u8 checksum; -+ u32 val; -+ -+ bp = 0; -+ tx->buf[bp++] = CHAR_SOF; -+ -+ checksum = ((msg->id & 0x0f) << 4) | (msg->tx_len & 0x0f); -+ tx->buf[bp++] = checksum; -+ -+ for (i = 0; i < msg->tx_len; i++) { -+ tx->buf[bp++] = msg->tx_data[i]; -+ checksum += msg->tx_data[i]; -+ } -+ -+ tx->buf[bp++] = checksum; -+ tx->len = bp; -+ tx->index = 0; -+ print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1, -+ tx->buf, tx->len, true); -+ -+ /* Enable interrupt */ -+ val = readl(micro->base + UTCR3); -+ val |= UTCR3_TIE; -+ writel(val, micro->base + UTCR3); -+} -+ -+int ipaq_micro_tx_msg(struct ipaq_micro *micro, struct ipaq_micro_msg *msg) -+{ -+ unsigned long flags; -+ -+ dev_dbg(micro->dev, "TX msg: %02x, %d bytes\n", msg->id, msg->tx_len); -+ -+ spin_lock_irqsave(µ->lock, flags); -+ if (micro->msg) { -+ list_add_tail(&msg->node, µ->queue); -+ spin_unlock_irqrestore(µ->lock, flags); -+ return 0; -+ } -+ micro->msg = msg; -+ ipaq_micro_trigger_tx(micro); -+ spin_unlock_irqrestore(µ->lock, flags); -+ return 0; -+} -+EXPORT_SYMBOL(ipaq_micro_tx_msg); -+ -+static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data) -+{ -+ int i; -+ -+ dev_dbg(micro->dev, "RX msg: %02x, %d bytes\n", id, len); -+ -+ spin_lock(µ->lock); -+ switch (id) { -+ case MSG_VERSION: -+ case MSG_EEPROM_READ: -+ case MSG_EEPROM_WRITE: -+ case MSG_BACKLIGHT: -+ case MSG_NOTIFY_LED: -+ case MSG_THERMAL_SENSOR: -+ case MSG_BATTERY: -+ /* Handle synchronous messages */ -+ if (micro->msg && micro->msg->id == id) { -+ struct ipaq_micro_msg *msg = micro->msg; -+ -+ memcpy(msg->rx_data, data, len); -+ msg->rx_len = len; -+ complete(µ->msg->ack); -+ if (!list_empty(µ->queue)) { -+ micro->msg = list_entry(micro->queue.next, -+ struct ipaq_micro_msg, -+ node); -+ list_del_init(µ->msg->node); -+ ipaq_micro_trigger_tx(micro); -+ } else -+ micro->msg = NULL; -+ dev_dbg(micro->dev, "OK RX message 0x%02x\n", id); -+ } else { -+ dev_err(micro->dev, -+ "out of band RX message 0x%02x\n", id); -+ if(!micro->msg) -+ dev_info(micro->dev, "no message queued\n"); -+ else -+ dev_info(micro->dev, "expected message %02x\n", -+ micro->msg->id); -+ } -+ break; -+ case MSG_KEYBOARD: -+ if (micro->key) -+ micro->key(micro->key_data, len, data); -+ else -+ dev_dbg(micro->dev, "key message ignored, no handle \n"); -+ break; -+ case MSG_TOUCHSCREEN: -+ if (micro->ts) -+ micro->ts(micro->ts_data, len, data); -+ else -+ dev_dbg(micro->dev, "touchscreen message ignored, no handle \n"); -+ break; -+ default: -+ dev_err(micro->dev, -+ "unknown msg %d [%d] ", id, len); -+ for (i = 0; i < len; ++i) -+ pr_cont("0x%02x ", data[i]); -+ pr_cont("\n"); -+ } -+ spin_unlock(µ->lock); -+} -+ -+static void micro_process_char(struct ipaq_micro *micro, u8 ch) -+{ -+ struct ipaq_micro_rxdev *rx = µ->rx; -+ -+ switch (rx->state) { -+ case STATE_SOF: /* Looking for SOF */ -+ if (ch == CHAR_SOF) -+ rx->state = STATE_ID; /* Next byte is the id and len */ -+ break; -+ case STATE_ID: /* Looking for id and len byte */ -+ rx->id = (ch & 0xf0) >> 4 ; -+ rx->len = (ch & 0x0f); -+ rx->index = 0; -+ rx->chksum = ch; -+ rx->state = (rx->len > 0) ? STATE_DATA : STATE_CHKSUM; -+ break; -+ case STATE_DATA: /* Looking for 'len' data bytes */ -+ rx->chksum += ch; -+ rx->buf[rx->index] = ch; -+ if (++rx->index == rx->len) -+ rx->state = STATE_CHKSUM; -+ break; -+ case STATE_CHKSUM: /* Looking for the checksum */ -+ if (ch == rx->chksum) -+ micro_rx_msg(micro, rx->id, rx->len, rx->buf); -+ rx->state = STATE_SOF; -+ break; -+ } -+} -+ -+static void micro_rx_chars(struct ipaq_micro *micro) -+{ -+ u32 status, ch; -+ -+ while ((status = readl(micro->base + UTSR1)) & UTSR1_RNE) { -+ ch = readl(micro->base + UTDR); -+ if (status & UTSR1_PRE) -+ dev_err(micro->dev, "rx: parity error\n"); -+ else if (status & UTSR1_FRE) -+ dev_err(micro->dev, "rx: framing error\n"); -+ else if (status & UTSR1_ROR) -+ dev_err(micro->dev, "rx: overrun error\n"); -+ micro_process_char(micro, ch); -+ } -+} -+ -+static void ipaq_micro_get_version(struct ipaq_micro *micro) -+{ -+ struct ipaq_micro_msg msg = { -+ .id = MSG_VERSION, -+ }; -+ -+ ipaq_micro_tx_msg_sync(micro, &msg); -+ if (msg.rx_len == 4) { -+ memcpy(micro->version, msg.rx_data, 4); -+ micro->version[4] = '\0'; -+ } else if (msg.rx_len == 9) { -+ memcpy(micro->version, msg.rx_data, 4); -+ micro->version[4] = '\0'; -+ /* Bytes 4-7 are "pack", byte 8 is "boot type" */ -+ } else { -+ dev_err(micro->dev, -+ "illegal version message %d bytes\n", msg.rx_len); -+ } -+} -+ -+static void ipaq_micro_eeprom_read(struct ipaq_micro *micro, -+ u8 address, u8 len, u8 *data) -+{ -+ struct ipaq_micro_msg msg = { -+ .id = MSG_EEPROM_READ, -+ }; -+ u8 i; -+ -+ for (i = 0; i < len; i++) { -+ msg.tx_data[0] = address + i; -+ msg.tx_data[1] = 1; -+ msg.tx_len = 2; -+ ipaq_micro_tx_msg_sync(micro, &msg); -+ memcpy(data + (i * 2), msg.rx_data, 2); -+ } -+} -+ -+static char *ipaq_micro_str(u8 *wchar, u8 len) -+{ -+ char retstr[256]; -+ u8 i; -+ -+ for (i = 0; i < len / 2; i++) -+ retstr[i] = wchar[i * 2]; -+ return kstrdup(retstr, GFP_KERNEL); -+} -+ -+static u16 ipaq_micro_to_u16(u8 *data) -+{ -+ return data[1] << 8 | data[0]; -+} -+ -+static void ipaq_micro_eeprom_dump(struct ipaq_micro *micro) -+{ -+ u8 dump[256]; -+ char *str; -+ -+ ipaq_micro_eeprom_read(micro, 0, 128, dump); -+ str = ipaq_micro_str(dump, 10); -+ if (str) { -+ dev_info(micro->dev, "HM version %s\n", str); -+ kfree(str); -+ } -+ str = ipaq_micro_str(dump+10, 40); -+ if (str) { -+ dev_info(micro->dev, "serial number: %s\n", str); -+ /* Feed the random pool with this */ -+ add_device_randomness(str, strlen(str)); -+ kfree(str); -+ } -+ str = ipaq_micro_str(dump+50, 20); -+ if (str) { -+ dev_info(micro->dev, "module ID: %s\n", str); -+ kfree(str); -+ } -+ str = ipaq_micro_str(dump+70, 10); -+ if (str) { -+ dev_info(micro->dev, "product revision: %s\n", str); -+ kfree(str); -+ } -+ dev_info(micro->dev, "product ID: %u\n", ipaq_micro_to_u16(dump+80)); -+ dev_info(micro->dev, "frame rate: %u fps\n", -+ ipaq_micro_to_u16(dump+82)); -+ dev_info(micro->dev, "page mode: %u\n", ipaq_micro_to_u16(dump+84)); -+ dev_info(micro->dev, "country ID: %u\n", ipaq_micro_to_u16(dump+86)); -+ dev_info(micro->dev, "color display: %s\n", -+ ipaq_micro_to_u16(dump+88) ? "yes" : "no"); -+ dev_info(micro->dev, "ROM size: %u MiB\n", ipaq_micro_to_u16(dump+90)); -+ dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92)); -+ dev_info(micro->dev, "screen: %u x %u\n", -+ ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96)); -+ print_hex_dump(KERN_DEBUG, "eeprom: ", DUMP_PREFIX_OFFSET, 16, 1, -+ dump, 256, true); -+ -+} -+ -+static void micro_tx_chars(struct ipaq_micro *micro) -+{ -+ struct ipaq_micro_txdev *tx = µ->tx; -+ u32 val; -+ -+ while ((tx->index < tx->len) && -+ (readl(micro->base + UTSR1) & UTSR1_TNF)) { -+ writel(tx->buf[tx->index], micro->base + UTDR); -+ tx->index++; -+ } -+ -+ /* Stop interrupts */ -+ val = readl(micro->base + UTCR3); -+ val &= ~UTCR3_TIE; -+ writel(val, micro->base + UTCR3); -+} -+ -+static void micro_reset_comm(struct ipaq_micro *micro) -+{ -+ struct ipaq_micro_rxdev *rx = µ->rx; -+ u32 val; -+ -+ if (micro->msg) -+ complete(µ->msg->ack); -+ -+ /* Initialize Serial channel protocol frame */ -+ rx->state = STATE_SOF; /* Reset the state machine */ -+ -+ /* Set up interrupts */ -+ writel(0x01, micro->sdlc + 0x0); /* Select UART mode */ -+ -+ /* Clean up CR3 */ -+ writel(0x0, micro->base + UTCR3); -+ -+ /* Format: 8N1 */ -+ writel(UTCR0_8BitData | UTCR0_1StpBit, micro->base + UTCR0); -+ -+ /* Baud rate: 115200 */ -+ writel(0x0, micro->base + UTCR1); -+ writel(0x1, micro->base + UTCR2); -+ -+ /* Clear SR0 */ -+ writel(0xff, micro->base + UTSR0); -+ -+ /* Enable RX int, disable TX int */ -+ writel(UTCR3_TXE | UTCR3_RXE | UTCR3_RIE, micro->base + UTCR3); -+ val = readl(micro->base + UTCR3); -+ val &= ~UTCR3_TIE; -+ writel(val, micro->base + UTCR3); -+} -+ -+static irqreturn_t micro_serial_isr(int irq, void *dev_id) -+{ -+ struct ipaq_micro *micro = dev_id; -+ struct ipaq_micro_txdev *tx = µ->tx; -+ u32 status; -+ -+ status = readl(micro->base + UTSR0); -+ do { -+ if (status & (UTSR0_RID | UTSR0_RFS)) { -+ if (status & UTSR0_RID) -+ /* Clear the Receiver IDLE bit */ -+ writel(UTSR0_RID, micro->base + UTSR0); -+ micro_rx_chars(micro); -+ } -+ -+ /* Clear break bits */ -+ if (status & (UTSR0_RBB | UTSR0_REB)) -+ writel(status & (UTSR0_RBB | UTSR0_REB), -+ micro->base + UTSR0); -+ -+ if (status & UTSR0_TFS) -+ micro_tx_chars(micro); -+ -+ status = readl(micro->base + UTSR0); -+ -+ } while (((tx->index < tx->len) && (status & UTSR0_TFS)) || -+ (status & (UTSR0_RFS | UTSR0_RID))); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct mfd_cell micro_cells[] = { -+ { .name = "ipaq-micro-backlight", }, -+ { .name = "ipaq-micro-battery", }, -+ { .name = "ipaq-micro-keys", }, -+ { .name = "ipaq-micro-ts", }, -+ { .name = "ipaq-micro-leds", }, -+}; -+ -+static int micro_suspend(struct device *dev) -+{ -+ return 0; -+} -+ -+static int micro_resume(struct device *dev) -+{ -+ struct ipaq_micro *micro = dev_get_drvdata(dev); -+ -+ micro_reset_comm(micro); -+ mdelay(10); -+ -+ return 0; -+} -+ -+static int micro_probe(struct platform_device *pdev) -+{ -+ struct ipaq_micro *micro; -+ struct resource *res; -+ int ret; -+ int irq; -+ -+ micro = devm_kzalloc(&pdev->dev, sizeof(*micro), GFP_KERNEL); -+ if (!micro) -+ return -ENOMEM; -+ -+ micro->dev = &pdev->dev; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -EINVAL; -+ -+ micro->base = devm_request_and_ioremap(&pdev->dev, res); -+ if (!micro->base) -+ return -ENOMEM; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!res) -+ return -EINVAL; -+ -+ micro->sdlc = devm_request_and_ioremap(&pdev->dev, res); -+ if (!micro->sdlc) -+ return -ENOMEM; -+ -+ micro_reset_comm(micro); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (!irq) -+ return -EINVAL; -+ ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr, -+ IRQF_SHARED, "ipaq-micro", -+ micro); -+ if (ret) { -+ dev_err(&pdev->dev, "unable to grab serial port IRQ\n"); -+ return ret; -+ } else -+ dev_info(&pdev->dev, "grabbed serial port IRQ\n"); -+ -+ spin_lock_init(µ->lock); -+ INIT_LIST_HEAD(µ->queue); -+ platform_set_drvdata(pdev, micro); -+ -+ ret = mfd_add_devices(&pdev->dev, pdev->id, micro_cells, -+ ARRAY_SIZE(micro_cells), NULL, 0, NULL); -+ if (ret) { -+ dev_err(&pdev->dev, "error adding MFD cells"); -+ return ret; -+ } -+ -+ /* Check version */ -+ ipaq_micro_get_version(micro); -+ dev_info(&pdev->dev, "Atmel micro ASIC version %s\n", micro->version); -+ ipaq_micro_eeprom_dump(micro); -+ -+ return 0; -+} -+ -+static int micro_remove(struct platform_device *pdev) -+{ -+ struct ipaq_micro *micro = platform_get_drvdata(pdev); -+ u32 val; -+ -+ mfd_remove_devices(&pdev->dev); -+ -+ val = readl(micro->base + UTCR3); -+ val &= ~(UTCR3_RXE | UTCR3_RIE); /* disable receive interrupt */ -+ val &= ~(UTCR3_TXE | UTCR3_TIE); /* disable transmit interrupt */ -+ writel(val, micro->base + UTCR3); -+ -+ return 0; -+} -+ -+static const struct dev_pm_ops micro_dev_pm_ops = { -+ SET_SYSTEM_SLEEP_PM_OPS(micro_suspend, micro_resume) -+}; -+ -+static struct platform_driver micro_device_driver = { -+ .driver = { -+ .name = "ipaq-h3xxx-micro", -+ .pm = µ_dev_pm_ops, -+ }, -+ .probe = micro_probe, -+ .remove = micro_remove, -+ /* .shutdown = micro_suspend, // FIXME */ -+}; -+module_platform_driver(micro_device_driver); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("driver for iPAQ Atmel micro core and backlight"); -diff --git a/include/linux/mfd/ipaq-micro.h b/include/linux/mfd/ipaq-micro.h -new file mode 100644 -index 000000000000..5c4d29f6674f ---- /dev/null -+++ b/include/linux/mfd/ipaq-micro.h -@@ -0,0 +1,148 @@ -+/* -+ * Header file for the compaq Micro MFD -+ */ -+ -+#ifndef _MFD_IPAQ_MICRO_H_ -+#define _MFD_IPAQ_MICRO_H_ -+ -+#include <linux/spinlock.h> -+#include <linux/completion.h> -+#include <linux/list.h> -+ -+#define TX_BUF_SIZE 32 -+#define RX_BUF_SIZE 16 -+#define CHAR_SOF 0x02 -+ -+/* -+ * These are the different messages that can be sent to the microcontroller -+ * to control various aspects. -+ */ -+#define MSG_VERSION 0x0 -+#define MSG_KEYBOARD 0x2 -+#define MSG_TOUCHSCREEN 0x3 -+#define MSG_EEPROM_READ 0x4 -+#define MSG_EEPROM_WRITE 0x5 -+#define MSG_THERMAL_SENSOR 0x6 -+#define MSG_NOTIFY_LED 0x8 -+#define MSG_BATTERY 0x9 -+#define MSG_SPI_READ 0xb -+#define MSG_SPI_WRITE 0xc -+#define MSG_BACKLIGHT 0xd /* H3600 only */ -+#define MSG_CODEC_CTRL 0xe /* H3100 only */ -+#define MSG_DISPLAY_CTRL 0xf /* H3100 only */ -+ -+/* state of receiver parser */ -+enum rx_state { -+ STATE_SOF = 0, /* Next byte should be start of frame */ -+ STATE_ID, /* Next byte is ID & message length */ -+ STATE_DATA, /* Next byte is a data byte */ -+ STATE_CHKSUM /* Next byte should be checksum */ -+}; -+ -+/** -+ * struct ipaq_micro_txdev - TX state -+ * @len: length of message in TX buffer -+ * @index: current index into TX buffer -+ * @buf: TX buffer -+ */ -+struct ipaq_micro_txdev { -+ u8 len; -+ u8 index; -+ u8 buf[TX_BUF_SIZE]; -+}; -+ -+/** -+ * struct ipaq_micro_rxdev - RX state -+ * @state: context of RX state machine -+ * @chksum: calculated checksum -+ * @id: message ID from packet -+ * @len: RX buffer length -+ * @index: RX buffer index -+ * @buf: RX buffer -+ */ -+struct ipaq_micro_rxdev { -+ enum rx_state state; -+ unsigned char chksum; -+ u8 id; -+ unsigned int len; -+ unsigned int index; -+ u8 buf[RX_BUF_SIZE]; -+}; -+ -+/** -+ * struct ipaq_micro_msg - message to the iPAQ microcontroller -+ * @id: 4-bit ID of the message -+ * @tx_len: length of TX data -+ * @tx_data: TX data to send -+ * @rx_len: length of receieved RX data -+ * @rx_data: RX data to recieve -+ * @ack: a completion that will be completed when RX is complete -+ * @node: list node if message gets queued -+ */ -+struct ipaq_micro_msg { -+ u8 id; -+ u8 tx_len; -+ u8 tx_data[TX_BUF_SIZE]; -+ u8 rx_len; -+ u8 rx_data[RX_BUF_SIZE]; -+ struct completion ack; -+ struct list_head node; -+}; -+ -+/** -+ * struct ipaq_micro - iPAQ microcontroller state -+ * @dev: corresponding platform device -+ * @base: virtual memory base for underlying serial device -+ * @sdlc: virtual memory base for Synchronous Data Link Controller -+ * @version: version string -+ * @tx: TX state -+ * @rx: RX state -+ * @lock: lock for this state container -+ * @msg: current message -+ * @queue: message queue -+ * @key: callback for asynchronous key events -+ * @key_data: data to pass along with key events -+ * @ts: callback for asynchronous touchscreen events -+ * @ts_data: data to pass along with key events -+ */ -+struct ipaq_micro { -+ struct device *dev; -+ void __iomem *base; -+ void __iomem *sdlc; -+ char version[5]; -+ struct ipaq_micro_txdev tx; /* transmit ISR state */ -+ struct ipaq_micro_rxdev rx; /* receive ISR state */ -+ spinlock_t lock; -+ struct ipaq_micro_msg *msg; -+ struct list_head queue; -+ void (*key) (void *data, int len, unsigned char *rxdata); -+ void *key_data; -+ void (*ts) (void *data, int len, unsigned char *rxdata); -+ void *ts_data; -+}; -+ -+extern int -+ipaq_micro_tx_msg(struct ipaq_micro *micro, struct ipaq_micro_msg *msg); -+ -+static inline int -+ipaq_micro_tx_msg_sync(struct ipaq_micro *micro, -+ struct ipaq_micro_msg *msg) -+{ -+ int ret; -+ -+ init_completion(&msg->ack); -+ ret = ipaq_micro_tx_msg(micro, msg); -+ wait_for_completion(&msg->ack); -+ -+ return ret; -+} -+ -+static inline int -+ipaq_micro_tx_msg_async(struct ipaq_micro *micro, -+ struct ipaq_micro_msg *msg) -+{ -+ init_completion(&msg->ack); -+ return ipaq_micro_tx_msg(micro, msg); -+} -+ -+#endif /* _MFD_IPAQ_MICRO_H_ */ --- -1.9.0 - |