diff options
author | Koen Kooi <koen@openembedded.org> | 2009-12-22 11:38:07 +0100 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-12-22 11:41:05 +0100 |
commit | ecf45a2c35bf51b7cf9e251611381872db68970d (patch) | |
tree | e55ff082ba109a699ce98db023b146288afbf5fa | |
parent | 96ef8994798341d274bcf9acf62efb69c14632ca (diff) |
linux-omap 2.6.32: add some more patches
17 files changed, 2069 insertions, 1 deletions
diff --git a/recipes/linux/linux-omap-2.6.32/0001-ARM-OMAP-Overo-Add-support-for-second-ethernet-po.patch b/recipes/linux/linux-omap-2.6.32/0001-ARM-OMAP-Overo-Add-support-for-second-ethernet-po.patch new file mode 100644 index 0000000000..3254fe4562 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0001-ARM-OMAP-Overo-Add-support-for-second-ethernet-po.patch @@ -0,0 +1,110 @@ +From 190c75031e65008425dbdd74c3e3237beed18460 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <sakoman@gmail.com> +Date: Tue, 15 Dec 2009 14:59:42 -0800 +Subject: [PATCH 01/16] ARM: OMAP: Overo: Add support for second ethernet port + +Signed-off-by: Steve Sakoman <sakoman@gmail.com> +--- + arch/arm/mach-omap2/board-overo.c | 56 +++++++++++++++++++++++++++++++++++-- + 1 files changed, 53 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c +index 52dfd51..1b94f2c 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -63,6 +63,8 @@ + + #define OVERO_SMSC911X_CS 5 + #define OVERO_SMSC911X_GPIO 176 ++#define OVERO_SMSC911X2_CS 4 ++#define OVERO_SMSC911X2_GPIO 65 + + #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +@@ -137,6 +139,16 @@ static struct resource overo_smsc911x_resources[] = { + }, + }; + ++static struct resource overo_smsc911x2_resources[] = { ++ { ++ .name = "smsc911x2-memory", ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, ++ }, ++}; ++ + static struct smsc911x_platform_config overo_smsc911x_config = { + .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, + .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, +@@ -146,7 +158,7 @@ static struct smsc911x_platform_config overo_smsc911x_config = { + + static struct platform_device overo_smsc911x_device = { + .name = "smsc911x", +- .id = -1, ++ .id = 0, + .num_resources = ARRAY_SIZE(overo_smsc911x_resources), + .resource = overo_smsc911x_resources, + .dev = { +@@ -154,9 +166,26 @@ static struct platform_device overo_smsc911x_device = { + }, + }; + ++static struct platform_device overo_smsc911x2_device = { ++ .name = "smsc911x", ++ .id = 1, ++ .num_resources = ARRAY_SIZE(overo_smsc911x2_resources), ++ .resource = overo_smsc911x2_resources, ++ .dev = { ++ .platform_data = &overo_smsc911x_config, ++ }, ++}; ++ ++static struct platform_device *smsc911x_devices[] = { ++ &overo_smsc911x_device, ++ &overo_smsc911x2_device, ++}; ++ + static inline void __init overo_init_smsc911x(void) + { +- unsigned long cs_mem_base; ++ unsigned long cs_mem_base, cs_mem_base2; ++ ++ /* set up first smsc911x chip */ + + if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) { + printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n"); +@@ -177,7 +206,28 @@ static inline void __init overo_init_smsc911x(void) + overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO); + overo_smsc911x_resources[1].end = 0; + +- platform_device_register(&overo_smsc911x_device); ++ /* set up second smsc911x chip */ ++ ++ if (gpmc_cs_request(OVERO_SMSC911X2_CS, SZ_16M, &cs_mem_base2) < 0) { ++ printk(KERN_ERR "Failed request for GPMC mem for smsc911x2\n"); ++ return; ++ } ++ ++ overo_smsc911x2_resources[0].start = cs_mem_base2 + 0x0; ++ overo_smsc911x2_resources[0].end = cs_mem_base2 + 0xff; ++ ++ if ((gpio_request(OVERO_SMSC911X2_GPIO, "SMSC911X2 IRQ") == 0) && ++ (gpio_direction_input(OVERO_SMSC911X2_GPIO) == 0)) { ++ gpio_export(OVERO_SMSC911X2_GPIO, 0); ++ } else { ++ printk(KERN_ERR "could not obtain gpio for SMSC911X2 IRQ\n"); ++ return; ++ } ++ ++ overo_smsc911x2_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X2_GPIO); ++ overo_smsc911x2_resources[1].end = 0; ++ ++ platform_add_devices(smsc911x_devices, ARRAY_SIZE(smsc911x_devices)); + } + + #else +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0002-ARM-OMAP-ehci-omap-use-new-location-for-usb.h-inc.patch b/recipes/linux/linux-omap-2.6.32/0002-ARM-OMAP-ehci-omap-use-new-location-for-usb.h-inc.patch new file mode 100644 index 0000000000..7add534bc7 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0002-ARM-OMAP-ehci-omap-use-new-location-for-usb.h-inc.patch @@ -0,0 +1,25 @@ +From 06e97c7ea488e350b7aae5f3864a1bbe0666db87 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Tue, 15 Dec 2009 15:12:54 -0800 +Subject: [PATCH 02/16] ARM: OMAP: ehci-omap: use new location for usb.h include + +--- + drivers/usb/host/ehci-omap.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index 7ba8df3..5cfed78 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -37,7 +37,7 @@ + #include <linux/platform_device.h> + #include <linux/clk.h> + #include <linux/gpio.h> +-#include <mach/usb.h> ++#include <plat/usb.h> + + /* + * OMAP USBHOST Register addresses: VIRTUAL ADDRESSES +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0003-drivers-net-smsc911x-return-ENODEV-if-device-is-n.patch b/recipes/linux/linux-omap-2.6.32/0003-drivers-net-smsc911x-return-ENODEV-if-device-is-n.patch new file mode 100644 index 0000000000..c15cf3a396 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0003-drivers-net-smsc911x-return-ENODEV-if-device-is-n.patch @@ -0,0 +1,29 @@ +From 196c189ca20294fdcef264995f68cca74b1e16ea Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <sakoman@gmail.com> +Date: Tue, 15 Dec 2009 15:17:44 -0800 +Subject: [PATCH 03/16] drivers: net: smsc911x: return ENODEV if device is not found + +Signed-off-by: Steve Sakoman <sakoman@gmail.com> +--- + drivers/net/smsc911x.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c +index f9cdcbc..9ca18b5 100644 +--- a/drivers/net/smsc911x.c ++++ b/drivers/net/smsc911x.c +@@ -2021,8 +2021,10 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) + } + + retval = smsc911x_init(dev); +- if (retval < 0) ++ if (retval < 0) { ++ retval = -ENODEV; + goto out_unmap_io_3; ++ } + + /* configure irq polarity and type before connecting isr */ + if (pdata->config.irq_polarity == SMSC911X_IRQ_POLARITY_ACTIVE_HIGH) +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0004-drivers-input-touchscreen-ads7846-return-ENODEV.patch b/recipes/linux/linux-omap-2.6.32/0004-drivers-input-touchscreen-ads7846-return-ENODEV.patch new file mode 100644 index 0000000000..345213cb59 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0004-drivers-input-touchscreen-ads7846-return-ENODEV.patch @@ -0,0 +1,53 @@ +From deb568b94c448aa7ffcc9e6788bcf9069fd3b864 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <sakoman@gmail.com> +Date: Tue, 15 Dec 2009 15:24:10 -0800 +Subject: [PATCH 04/16] drivers: input: touchscreen: ads7846: return ENODEV if device is not found + +Signed-off-by: Steve Sakoman <sakoman@gmail.com> +--- + drivers/input/touchscreen/ads7846.c | 13 ++++++++++--- + 1 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c +index 09c8109..7cc9973 100644 +--- a/drivers/input/touchscreen/ads7846.c ++++ b/drivers/input/touchscreen/ads7846.c +@@ -1170,9 +1170,16 @@ static int __devinit ads7846_probe(struct spi_device *spi) + /* take a first sample, leaving nPENIRQ active and vREF off; avoid + * the touchscreen, in case it's not connected. + */ +- (void) ads7846_read12_ser(&spi->dev, ++ err = ads7846_read12_ser(&spi->dev, + READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); + ++ /* if sample is all 0's or all 1's then there is no device on spi */ ++ if ( (err == 0x000) || (err == 0xfff)) { ++ dev_info(&spi->dev, "no device detected, test read result was 0x%08X\n", err); ++ err = -ENODEV; ++ goto err_free_irq; ++ } ++ + err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group); + if (err) + goto err_remove_hwmon; +@@ -1190,7 +1197,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) + err_free_irq: + free_irq(spi->irq, ts); + err_free_gpio: +- if (ts->gpio_pendown != -1) ++ if (!ts->get_pendown_state && ts->gpio_pendown != -1) + gpio_free(ts->gpio_pendown); + err_cleanup_filter: + if (ts->filter_cleanup) +@@ -1217,7 +1224,7 @@ static int __devexit ads7846_remove(struct spi_device *spi) + /* suspend left the IRQ disabled */ + enable_irq(ts->spi->irq); + +- if (ts->gpio_pendown != -1) ++ if (!ts->get_pendown_state && ts->gpio_pendown != -1) + gpio_free(ts->gpio_pendown); + + if (ts->filter_cleanup) +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0005-ARM-OMAP-add-support-for-TCT-Zippy-to-Beagle-board.patch b/recipes/linux/linux-omap-2.6.32/0005-ARM-OMAP-add-support-for-TCT-Zippy-to-Beagle-board.patch new file mode 100644 index 0000000000..1c51552792 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0005-ARM-OMAP-add-support-for-TCT-Zippy-to-Beagle-board.patch @@ -0,0 +1,135 @@ +From 334eef94045c93957cad3477522086492dd19b06 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <sakoman@gmail.com> +Date: Tue, 15 Dec 2009 15:34:29 -0800 +Subject: [PATCH 05/16] ARM: OMAP: add support for TCT Zippy to Beagle board file + +Signed-off-by: Steve Sakoman <sakoman@gmail.com> +--- + arch/arm/mach-omap2/board-omap3beagle.c | 74 +++++++++++++++++++++++++++++- + 1 files changed, 71 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 41480bd..f3df638 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -21,6 +21,7 @@ + #include <linux/io.h> + #include <linux/leds.h> + #include <linux/gpio.h> ++#include <linux/irq.h> + #include <linux/input.h> + #include <linux/gpio_keys.h> + +@@ -52,6 +53,49 @@ + + #define NAND_BLOCK_SIZE SZ_128K + ++#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE) ++ ++#include <plat/mcspi.h> ++#include <linux/spi/spi.h> ++ ++#define OMAP3BEAGLE_GPIO_ENC28J60_IRQ 157 ++ ++static struct omap2_mcspi_device_config enc28j60_spi_chip_info = { ++ .turbo_mode = 0, ++ .single_channel = 1, /* 0: slave, 1: master */ ++}; ++ ++static struct spi_board_info omap3beagle_spi_board_info[] __initdata = { ++ { ++ .modalias = "enc28j60", ++ .bus_num = 4, ++ .chip_select = 0, ++ .max_speed_hz = 20000000, ++ .controller_data = &enc28j60_spi_chip_info, ++ }, ++}; ++ ++static void __init omap3beagle_enc28j60_init(void) ++{ ++ if ((gpio_request(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, "ENC28J60_IRQ") == 0) && ++ (gpio_direction_input(OMAP3BEAGLE_GPIO_ENC28J60_IRQ) == 0)) { ++ gpio_export(OMAP3BEAGLE_GPIO_ENC28J60_IRQ, 0); ++ omap3beagle_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ); ++ set_irq_type(omap3beagle_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING); ++ } else { ++ printk(KERN_ERR "could not obtain gpio for ENC28J60_IRQ\n"); ++ return; ++ } ++ ++ spi_register_board_info(omap3beagle_spi_board_info, ++ ARRAY_SIZE(omap3beagle_spi_board_info)); ++} ++ ++#else ++static inline void __init omap3beagle_enc28j60_init(void) { return; } ++#endif ++ ++ + static struct mtd_partition omap3beagle_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { +@@ -114,6 +158,14 @@ static struct twl4030_hsmmc_info mmc[] = { + .wires = 8, + .gpio_wp = 29, + }, ++ { ++ .mmc = 2, ++ .wires = 4, ++ .gpio_wp = 141, ++ .gpio_cd = 162, ++ .transceiver = true, ++ .ocr_mask = 0x00100000, /* 3.3V */ ++ }, + {} /* Terminator */ + }; + +@@ -277,7 +329,7 @@ static struct twl4030_platform_data beagle_twldata = { + .vpll2 = &beagle_vpll2, + }; + +-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { ++static struct i2c_board_info __initdata beagle_i2c1_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, +@@ -286,10 +338,24 @@ static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = { + }, + }; + ++#if defined(CONFIG_RTC_DRV_DS1307) || \ ++ defined(CONFIG_RTC_DRV_DS1307_MODULE) ++ ++static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = { ++ { ++ I2C_BOARD_INFO("ds1307", 0x68), ++ }, ++}; ++#else ++static struct i2c_board_info __initdata beagle_i2c2_boardinfo[] = {}; ++#endif ++ + static int __init omap3_beagle_i2c_init(void) + { +- omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo, +- ARRAY_SIZE(beagle_i2c_boardinfo)); ++ omap_register_i2c_bus(1, 2600, beagle_i2c1_boardinfo, ++ ARRAY_SIZE(beagle_i2c1_boardinfo)); ++ omap_register_i2c_bus(2, 400, beagle_i2c2_boardinfo, ++ ARRAY_SIZE(beagle_i2c2_boardinfo)); + /* Bus 3 is attached to the DVI port where devices like the pico DLP + * projector don't work reliably with 400kHz */ + omap_register_i2c_bus(3, 100, NULL, 0); +@@ -434,6 +500,8 @@ static void __init omap3_beagle_init(void) + /* REVISIT leave DVI powered down until it's needed ... */ + gpio_direction_output(170, true); + ++ omap3beagle_enc28j60_init(); ++ + usb_musb_init(); + usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0006-ARM-OMAP-Make-beagle-u-boot-partition-writable.patch b/recipes/linux/linux-omap-2.6.32/0006-ARM-OMAP-Make-beagle-u-boot-partition-writable.patch new file mode 100644 index 0000000000..3ad1853e3f --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0006-ARM-OMAP-Make-beagle-u-boot-partition-writable.patch @@ -0,0 +1,24 @@ +From 2607d201fb202499533aa4a7fc788b4fa5fd1fcf Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 12:40:24 -0800 +Subject: [PATCH 06/16] ARM: OMAP: Make beagle u-boot partition writable + +--- + arch/arm/mach-omap2/board-omap3beagle.c | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index f3df638..d00b089 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -108,7 +108,6 @@ static struct mtd_partition omap3beagle_nand_partitions[] = { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, +- .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot Env", +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0007-ASoC-enable-audio-capture-by-default-for-twl4030.patch b/recipes/linux/linux-omap-2.6.32/0007-ASoC-enable-audio-capture-by-default-for-twl4030.patch new file mode 100644 index 0000000000..6ad4366f02 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0007-ASoC-enable-audio-capture-by-default-for-twl4030.patch @@ -0,0 +1,27 @@ +From a0cf94cd5d99280fccc29e6b7777c448f15d1c65 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 12:45:20 -0800 +Subject: [PATCH 07/16] ASoC: enable audio capture by default for twl4030 + +--- + sound/soc/codecs/twl4030.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c +index 4df7c6c..e85db73 100644 +--- a/sound/soc/codecs/twl4030.c ++++ b/sound/soc/codecs/twl4030.c +@@ -46,8 +46,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { + 0xc3, /* REG_OPTION (0x2) */ + 0x00, /* REG_UNKNOWN (0x3) */ + 0x00, /* REG_MICBIAS_CTL (0x4) */ +- 0x20, /* REG_ANAMICL (0x5) */ +- 0x00, /* REG_ANAMICR (0x6) */ ++ 0x34, /* REG_ANAMICL (0x5) */ ++ 0x14, /* REG_ANAMICR (0x6) */ + 0x00, /* REG_AVADC_CTL (0x7) */ + 0x00, /* REG_ADCMICSEL (0x8) */ + 0x00, /* REG_DIGMIXING (0x9) */ +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/0008-scripts-Makefile.fwinst-fix-typo-missing-space-in.patch b/recipes/linux/linux-omap-2.6.32/0008-scripts-Makefile.fwinst-fix-typo-missing-space-in.patch new file mode 100644 index 0000000000..9b5ccaac69 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/0008-scripts-Makefile.fwinst-fix-typo-missing-space-in.patch @@ -0,0 +1,25 @@ +From ce9fc5ab828b050605eb7d916f64ace7b227eea6 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 12:51:53 -0800 +Subject: [PATCH 08/16] scripts/Makefile.fwinst: fix typo (missing space in setting mode) + +--- + scripts/Makefile.fwinst | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst +index 6bf8e87..fb20532 100644 +--- a/scripts/Makefile.fwinst ++++ b/scripts/Makefile.fwinst +@@ -37,7 +37,7 @@ install-all-dirs: $(installed-fw-dirs) + @true + + quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@) +- cmd_install = $(INSTALL) -m0644 $< $@ ++ cmd_install = $(INSTALL) -m 0644 $< $@ + + $(installed-fw-dirs): + $(call cmd,mkdir) +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/dss2/0012-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-pane.patch b/recipes/linux/linux-omap-2.6.32/dss2/0012-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-pane.patch new file mode 100644 index 0000000000..a22f3e712f --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/dss2/0012-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-pane.patch @@ -0,0 +1,254 @@ +From e09abf20005e9abf41e44e712bc600d2cb346cb5 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 15:05:30 -0800 +Subject: [PATCH 12/16] OMAP: DSS2: Add support for LG Philips LB035Q02 panel + +--- + drivers/video/omap2/displays/Kconfig | 6 + + drivers/video/omap2/displays/Makefile | 1 + + .../omap2/displays/panel-lgphilips-lb035q02.c | 206 ++++++++++++++++++++ + 3 files changed, 213 insertions(+), 0 deletions(-) + create mode 100644 drivers/video/omap2/displays/panel-lgphilips-lb035q02.c + +diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig +index 79d2861..050f29c 100644 +--- a/drivers/video/omap2/displays/Kconfig ++++ b/drivers/video/omap2/displays/Kconfig +@@ -7,6 +7,12 @@ config PANEL_GENERIC + Generic panel driver. + Used for DVI output for Beagle and OMAP3 SDP. + ++config PANEL_LGPHILIPS_LB035Q02 ++ tristate "LG.Philips LB035Q02 LCD Panel" ++ depends on OMAP2_DSS ++ help ++ LCD Panel used on Overo Palo35 ++ + config PANEL_SAMSUNG_LTE430WQ_F0C + tristate "Samsung LTE430WQ-F0C LCD Panel" + depends on OMAP2_DSS +diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile +index d44e765..28f6f9b 100644 +--- a/drivers/video/omap2/displays/Makefile ++++ b/drivers/video/omap2/displays/Makefile +@@ -1,4 +1,5 @@ + obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o ++obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o + obj-$(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) += panel-samsung-lte430wq-f0c.o + obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o + +diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +new file mode 100644 +index 0000000..22dc865 +--- /dev/null ++++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +@@ -0,0 +1,206 @@ ++/* ++ * LCD panel driver for LG.Philips LB035Q02 ++ * ++ * Author: Steve Sakoman <steve@sakoman.com> ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/module.h> ++#include <linux/delay.h> ++#include <linux/spi/spi.h> ++ ++#include <plat/display.h> ++ ++static struct spi_device *spidev; ++ ++static struct omap_video_timings lb035q02_timings = { ++ .x_res = 320, ++ .y_res = 240, ++ ++ .pixel_clock = 6500, ++ ++ .hsw = 2, ++ .hfp = 20, ++ .hbp = 68, ++ ++ .vsw = 2, ++ .vfp = 4, ++ .vbp = 18, ++}; ++ ++static int lb035q02_panel_probe(struct omap_dss_device *dssdev) ++{ ++ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | ++ OMAP_DSS_LCD_IHS; ++ dssdev->panel.timings = lb035q02_timings; ++ ++ return 0; ++} ++ ++static void lb035q02_panel_remove(struct omap_dss_device *dssdev) ++{ ++} ++ ++static int lb035q02_write_reg(u8 reg, u16 val) ++{ ++ struct spi_message msg; ++ struct spi_transfer index_xfer = { ++ .len = 3, ++ .cs_change = 1, ++ }; ++ struct spi_transfer value_xfer = { ++ .len = 3, ++ }; ++ u8 buffer[16]; ++ ++ spi_message_init(&msg); ++ ++ /* register index */ ++ buffer[0] = 0x70; ++ buffer[1] = 0x00; ++ buffer[2] = reg & 0x7f; ++ index_xfer.tx_buf = buffer; ++ spi_message_add_tail(&index_xfer, &msg); ++ ++ /* register value */ ++ buffer[4] = 0x72; ++ buffer[5] = val >> 8; ++ buffer[6] = val; ++ value_xfer.tx_buf = buffer + 4; ++ spi_message_add_tail(&value_xfer, &msg); ++ ++ return spi_sync(spidev, &msg); ++} ++ ++static int lb035q02_panel_enable(struct omap_dss_device *dssdev) ++{ ++ int r = 0; ++ ++ pr_info("lgphilips_lb035q02: panel_enable: 0x%08x\n", spidev); ++ /* wait couple of vsyncs until enabling the LCD */ ++ msleep(50); ++ ++ if (dssdev->platform_enable) ++ r = dssdev->platform_enable(dssdev); ++ ++ /* Panel init sequence from page 28 of the spec */ ++ lb035q02_write_reg(0x01, 0x6300); ++ lb035q02_write_reg(0x02, 0x0200); ++ lb035q02_write_reg(0x03, 0x0177); ++ lb035q02_write_reg(0x04, 0x04c7); ++ lb035q02_write_reg(0x05, 0xffc0); ++ lb035q02_write_reg(0x06, 0xe806); ++ lb035q02_write_reg(0x0a, 0x4008); ++ lb035q02_write_reg(0x0b, 0x0000); ++ lb035q02_write_reg(0x0d, 0x0030); ++ lb035q02_write_reg(0x0e, 0x2800); ++ lb035q02_write_reg(0x0f, 0x0000); ++ lb035q02_write_reg(0x16, 0x9f80); ++ lb035q02_write_reg(0x17, 0x0a0f); ++ lb035q02_write_reg(0x1e, 0x00c1); ++ lb035q02_write_reg(0x30, 0x0300); ++ lb035q02_write_reg(0x31, 0x0007); ++ lb035q02_write_reg(0x32, 0x0000); ++ lb035q02_write_reg(0x33, 0x0000); ++ lb035q02_write_reg(0x34, 0x0707); ++ lb035q02_write_reg(0x35, 0x0004); ++ lb035q02_write_reg(0x36, 0x0302); ++ lb035q02_write_reg(0x37, 0x0202); ++ lb035q02_write_reg(0x3a, 0x0a0d); ++ lb035q02_write_reg(0x3b, 0x0806); ++ ++ return r; ++} ++ ++static void lb035q02_panel_disable(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->platform_disable) ++ dssdev->platform_disable(dssdev); ++ ++ /* wait at least 5 vsyncs after disabling the LCD */ ++ ++ msleep(100); ++} ++ ++static int lb035q02_panel_suspend(struct omap_dss_device *dssdev) ++{ ++ pr_info("lgphilips_lb035q02: panel_suspend\n"); ++ lb035q02_panel_disable(dssdev); ++ return 0; ++} ++ ++static int lb035q02_panel_resume(struct omap_dss_device *dssdev) ++{ ++ pr_info("lgphilips_lb035q02: panel_resume\n"); ++ return lb035q02_panel_enable(dssdev); ++} ++ ++static struct omap_dss_driver lb035q02_driver = { ++ .probe = lb035q02_panel_probe, ++ .remove = lb035q02_panel_remove, ++ ++ .enable = lb035q02_panel_enable, ++ .disable = lb035q02_panel_disable, ++ .suspend = lb035q02_panel_suspend, ++ .resume = lb035q02_panel_resume, ++ ++ .driver = { ++ .name = "lgphilips_lb035q02_panel", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi) ++{ ++ spidev = spi; ++ return 0; ++} ++ ++static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi) ++{ ++ return 0; ++} ++ ++static struct spi_driver lb035q02_spi_driver = { ++ .driver = { ++ .name = "lgphilips_lb035q02_panel-spi", ++ .owner = THIS_MODULE, ++ }, ++ .probe = lb035q02_panel_spi_probe, ++ .remove = __devexit_p (lb035q02_panel_spi_remove), ++}; ++ ++static int __init lb035q02_panel_drv_init(void) ++{ ++ int ret; ++ ret = spi_register_driver(&lb035q02_spi_driver); ++ if (ret != 0) ++ pr_err("lgphilips_lb035q02: Unable to register SPI driver: %d\n", ret); ++ ++ ret = omap_dss_register_driver(&lb035q02_driver); ++ if (ret != 0) ++ pr_err("lgphilips_lb035q02: Unable to register panel driver: %d\n", ret); ++ ++ return ret; ++} ++ ++static void __exit lb035q02_panel_drv_exit(void) ++{ ++ spi_unregister_driver(&lb035q02_spi_driver); ++ omap_dss_unregister_driver(&lb035q02_driver); ++} ++ ++module_init(lb035q02_panel_drv_init); ++module_exit(lb035q02_panel_drv_exit); ++MODULE_LICENSE("GPL"); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/dss2/0014-OMAP-DSS-Add-DSS2-support-for-Overo.patch b/recipes/linux/linux-omap-2.6.32/dss2/0014-OMAP-DSS-Add-DSS2-support-for-Overo.patch new file mode 100644 index 0000000000..c673a09a76 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/dss2/0014-OMAP-DSS-Add-DSS2-support-for-Overo.patch @@ -0,0 +1,343 @@ +From 6b135653505a2a5da42c92cfa31c3ab22e2b130f Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Fri, 18 Dec 2009 06:39:24 -0800 +Subject: [PATCH 14/16] OMAP: DSS: Add DSS2 support for Overo + +--- + arch/arm/mach-omap2/board-overo.c | 233 +++++++++++++++++++++++++++++++----- + 1 files changed, 200 insertions(+), 33 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c +index d0394d9..b90b140 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -28,6 +28,7 @@ + #include <linux/platform_device.h> + #include <linux/i2c/twl4030.h> + #include <linux/regulator/machine.h> ++#include <linux/spi/spi.h> + + #include <linux/mtd/mtd.h> + #include <linux/mtd/nand.h> +@@ -40,10 +41,12 @@ + + #include <plat/board.h> + #include <plat/common.h> ++#include <plat/display.h> + #include <mach/gpio.h> + #include <plat/gpmc.h> + #include <mach/hardware.h> + #include <plat/nand.h> ++#include <plat/mcspi.h> + #include <plat/mux.h> + #include <plat/usb.h> + +@@ -69,8 +72,6 @@ + #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +-#include <plat/mcspi.h> +-#include <linux/spi/spi.h> + #include <linux/spi/ads7846.h> + + static struct omap2_mcspi_device_config ads7846_mcspi_config = { +@@ -95,18 +96,6 @@ static struct ads7846_platform_data ads7846_config = { + .keep_vref_on = 1, + }; + +-static struct spi_board_info overo_spi_board_info[] __initdata = { +- { +- .modalias = "ads7846", +- .bus_num = 1, +- .chip_select = 0, +- .max_speed_hz = 1500000, +- .controller_data = &ads7846_mcspi_config, +- .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), +- .platform_data = &ads7846_config, +- } +-}; +- + static void __init overo_ads7846_init(void) + { + if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) && +@@ -116,9 +105,6 @@ static void __init overo_ads7846_init(void) + printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n"); + return; + } +- +- spi_register_board_info(overo_spi_board_info, +- ARRAY_SIZE(overo_spi_board_info)); + } + + #else +@@ -234,6 +220,137 @@ static inline void __init overo_init_smsc911x(void) + static inline void __init overo_init_smsc911x(void) { return; } + #endif + ++/* DSS */ ++static int lcd_enabled; ++static int dvi_enabled; ++ ++#define OVERO_GPIO_LCD_EN 144 ++#define OVERO_GPIO_LCD_BL 145 ++ ++static void __init overo_display_init(void) ++{ ++ if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) && ++ (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0)) ++ gpio_export(OVERO_GPIO_LCD_EN, 0); ++ else ++ printk(KERN_ERR "could not obtain gpio for " ++ "OVERO_GPIO_LCD_EN\n"); ++ ++ if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) && ++ (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0)) ++ gpio_export(OVERO_GPIO_LCD_BL, 0); ++ else ++ printk(KERN_ERR "could not obtain gpio for " ++ "OVERO_GPIO_LCD_BL\n"); ++} ++ ++static int overo_panel_enable_dvi(struct omap_dss_device *dssdev) ++{ ++ if (lcd_enabled) { ++ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n"); ++ return -EINVAL; ++ } ++ dvi_enabled = 1; ++ ++ return 0; ++} ++ ++static void overo_panel_disable_dvi(struct omap_dss_device *dssdev) ++{ ++ dvi_enabled = 0; ++} ++ ++static struct omap_dss_device overo_dvi_device = { ++ .type = OMAP_DISPLAY_TYPE_DPI, ++ .name = "dvi", ++ .driver_name = "generic_panel", ++ .phy.dpi.data_lines = 24, ++ .platform_enable = overo_panel_enable_dvi, ++ .platform_disable = overo_panel_disable_dvi, ++}; ++ ++static int overo_panel_enable_lcd(struct omap_dss_device *dssdev) ++{ ++ if (dvi_enabled) { ++ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n"); ++ return -EINVAL; ++ } ++ ++ gpio_set_value(OVERO_GPIO_LCD_EN, 1); ++ gpio_set_value(OVERO_GPIO_LCD_BL, 1); ++ lcd_enabled = 1; ++ return 0; ++} ++ ++static void overo_panel_disable_lcd(struct omap_dss_device *dssdev) ++{ ++ gpio_set_value(OVERO_GPIO_LCD_EN, 0); ++ gpio_set_value(OVERO_GPIO_LCD_BL, 0); ++ lcd_enabled = 0; ++} ++ ++#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ ++ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) ++static struct omap_dss_device overo_lcd35_device = { ++ .type = OMAP_DISPLAY_TYPE_DPI, ++ .name = "lcd35", ++ .driver_name = "lgphilips_lb035q02_panel", ++ .phy.dpi.data_lines = 24, ++ .panel.recommended_bpp = 16, ++ .platform_enable = overo_panel_enable_lcd, ++ .platform_disable = overo_panel_disable_lcd, ++}; ++#endif ++ ++#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \ ++ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE) ++static struct omap_dss_device overo_lcd43_device = { ++ .type = OMAP_DISPLAY_TYPE_DPI, ++ .name = "lcd43", ++ .driver_name = "samsung_lte_panel", ++ .phy.dpi.data_lines = 24, ++ .panel.recommended_bpp = 16, ++ .platform_enable = overo_panel_enable_lcd, ++ .platform_disable = overo_panel_disable_lcd, ++}; ++#endif ++ ++static struct omap_dss_device *overo_dss_devices[] = { ++ &overo_dvi_device, ++#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ ++ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) ++ &overo_lcd35_device, ++#endif ++#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \ ++ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE) ++ &overo_lcd43_device, ++#endif ++}; ++ ++static struct omap_dss_board_info overo_dss_data = { ++ .num_devices = ARRAY_SIZE(overo_dss_devices), ++ .devices = overo_dss_devices, ++ .default_device = &overo_dvi_device, ++}; ++ ++static struct platform_device overo_dss_device = { ++ .name = "omapdss", ++ .id = -1, ++ .dev = { ++ .platform_data = &overo_dss_data, ++ }, ++}; ++ ++static struct regulator_consumer_supply overo_vdda_dac_supply = { ++ .supply = "vdda_dac", ++ .dev = &overo_dss_device.dev, ++}; ++ ++static struct regulator_consumer_supply overo_vdds_dsi_supply = { ++ .supply = "vdds_dsi", ++ .dev = &overo_dss_device.dev, ++}; ++ + static struct mtd_partition overo_nand_partitions[] = { + { + .name = "xloader", +@@ -379,6 +496,37 @@ static struct regulator_init_data overo_vmmc1 = { + .consumer_supplies = &overo_vmmc1_supply, + }; + ++/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ ++static struct regulator_init_data overo_vdac = { ++ .constraints = { ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL ++ | REGULATOR_MODE_STANDBY, ++ .valid_ops_mask = REGULATOR_CHANGE_MODE ++ | REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &overo_vdda_dac_supply, ++}; ++ ++/* VPLL2 for digital video outputs */ ++static struct regulator_init_data overo_vpll2 = { ++ .constraints = { ++ .name = "VDVI", ++ .min_uV = 1800000, ++ .max_uV = 1800000, ++ .valid_modes_mask = REGULATOR_MODE_NORMAL ++ | REGULATOR_MODE_STANDBY, ++ .valid_ops_mask = REGULATOR_CHANGE_MODE ++ | REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &overo_vdds_dsi_supply, ++}; ++ ++/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ ++ + static struct twl4030_codec_audio_data overo_audio_data = { + .audio_mclk = 26000000, + }; +@@ -388,8 +536,6 @@ static struct twl4030_codec_data overo_codec_data = { + .audio = &overo_audio_data, + }; + +-/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ +- + static struct twl4030_madc_platform_data overo_madc_data = { + .irq_line = 1, + }; +@@ -402,6 +548,8 @@ static struct twl4030_platform_data overo_twldata = { + .usb = &overo_usb_data, + .codec = &overo_codec_data, + .vmmc1 = &overo_vmmc1, ++ .vdac = &overo_vdac, ++ .vpll2 = &overo_vpll2, + }; + + static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { +@@ -422,23 +570,41 @@ static int __init overo_i2c_init(void) + return 0; + } + +-static struct platform_device overo_lcd_device = { +- .name = "overo_lcd", +- .id = -1, +-}; +- +-static struct omap_lcd_config overo_lcd_config __initdata = { +- .ctrl_name = "internal", ++static struct spi_board_info overo_spi_board_info[] __initdata = { ++#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ ++ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) ++ { ++ .modalias = "ads7846", ++ .bus_num = 1, ++ .chip_select = 0, ++ .max_speed_hz = 1500000, ++ .controller_data = &ads7846_mcspi_config, ++ .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), ++ .platform_data = &ads7846_config, ++ }, ++#endif ++#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ ++ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) ++ { ++ .modalias = "lgphilips_lb035q02_panel-spi", ++ .bus_num = 1, ++ .chip_select = 1, ++ .max_speed_hz = 500000, ++ .mode = SPI_MODE_3, ++ }, ++#endif + }; + +-static struct omap_board_config_kernel overo_config[] __initdata = { +- { OMAP_TAG_LCD, &overo_lcd_config }, +-}; ++static int __init overo_spi_init(void) ++{ ++ overo_ads7846_init(); ++ spi_register_board_info(overo_spi_board_info, ++ ARRAY_SIZE(overo_spi_board_info)); ++ return 0; ++} + + static void __init overo_init_irq(void) + { +- omap_board_config = overo_config; +- omap_board_config_size = ARRAY_SIZE(overo_config); + omap2_init_common_hw(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + omap_init_irq(); +@@ -446,7 +612,7 @@ static void __init overo_init_irq(void) + } + + static struct platform_device *overo_devices[] __initdata = { +- &overo_lcd_device, ++ &overo_dss_device, + }; + + static struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +@@ -469,8 +635,9 @@ static void __init overo_init(void) + overo_flash_init(); + usb_musb_init(); + usb_ehci_init(&ehci_pdata); +- overo_ads7846_init(); ++ overo_spi_init(); + overo_init_smsc911x(); ++ overo_display_init(); + + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_cfg_reg(H16_34XX_SDRC_CKE0); +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/dss2/0015-OMAP-DSS-Add-DSS2-support-for-Beagle.patch b/recipes/linux/linux-omap-2.6.32/dss2/0015-OMAP-DSS-Add-DSS2-support-for-Beagle.patch new file mode 100644 index 0000000000..656ba85318 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/dss2/0015-OMAP-DSS-Add-DSS2-support-for-Beagle.patch @@ -0,0 +1,186 @@ +--- /tmp/board-omap3beagle.c 2009-12-22 10:47:35.000000000 +0100 ++++ git/arch/arm/mach-omap2/board-omap3beagle.c 2009-12-22 10:59:53.000000000 +0100 +@@ -40,6 +40,7 @@ + + #include <plat/board.h> + #include <plat/common.h> ++#include <plat/display.h> + #include <plat/gpmc.h> + #include <plat/nand.h> + #include <plat/usb.h> +@@ -149,6 +150,105 @@ + .resource = &omap3beagle_nand_resource, + }; + ++/* DSS */ ++ ++static int beagle_enable_dvi(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->reset_gpio != -1) ++ gpio_set_value(dssdev->reset_gpio, 1); ++ ++ return 0; ++} ++ ++static void beagle_disable_dvi(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->reset_gpio != -1) ++ gpio_set_value(dssdev->reset_gpio, 0); ++} ++ ++static struct omap_dss_device beagle_dvi_device = { ++ .type = OMAP_DISPLAY_TYPE_DPI, ++ .name = "dvi", ++ .driver_name = "generic_panel", ++ .phy.dpi.data_lines = 24, ++ .reset_gpio = 170, ++ .platform_enable = beagle_enable_dvi, ++ .platform_disable = beagle_disable_dvi, ++}; ++ ++static int beagle_panel_enable_tv(struct omap_dss_device *dssdev) ++{ ++#define ENABLE_VDAC_DEDICATED 0x03 ++#define ENABLE_VDAC_DEV_GRP 0x20 ++ ++ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, ++ ENABLE_VDAC_DEDICATED, ++ TWL4030_VDAC_DEDICATED); ++ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, ++ ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP); ++ ++ return 0; ++} ++ ++static void beagle_panel_disable_tv(struct omap_dss_device *dssdev) ++{ ++ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00, ++ TWL4030_VDAC_DEDICATED); ++ twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00, ++ TWL4030_VDAC_DEV_GRP); ++} ++ ++static struct omap_dss_device beagle_tv_device = { ++ .name = "tv", ++ .driver_name = "venc", ++ .type = OMAP_DISPLAY_TYPE_VENC, ++ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, ++ .platform_enable = beagle_panel_enable_tv, ++ .platform_disable = beagle_panel_disable_tv, ++}; ++ ++static struct omap_dss_device *beagle_dss_devices[] = { ++ &beagle_dvi_device, ++ &beagle_tv_device, ++}; ++ ++static struct omap_dss_board_info beagle_dss_data = { ++ .num_devices = ARRAY_SIZE(beagle_dss_devices), ++ .devices = beagle_dss_devices, ++ .default_device = &beagle_dvi_device, ++}; ++ ++static struct platform_device beagle_dss_device = { ++ .name = "omapdss", ++ .id = -1, ++ .dev = { ++ .platform_data = &beagle_dss_data, ++ }, ++}; ++ ++static struct regulator_consumer_supply beagle_vdac_supply = { ++ .supply = "vdda_dac", ++ .dev = &beagle_dss_device.dev, ++}; ++ ++static struct regulator_consumer_supply beagle_vdvi_supply = { ++ .supply = "vdds_dsi", ++ .dev = &beagle_dss_device.dev, ++}; ++ ++static void __init beagle_display_init(void) ++{ ++ int r; ++ ++ r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset"); ++ if (r < 0) { ++ printk(KERN_ERR "Unable to get DVI reset GPIO\n"); ++ return; ++ } ++ ++ gpio_direction_output(beagle_dvi_device.reset_gpio, 0); ++} ++ + #include "sdram-micron-mt46h32m32lf-6.h" + + static struct twl4030_hsmmc_info mmc[] = { +@@ -168,15 +268,6 @@ + {} /* Terminator */ + }; + +-static struct platform_device omap3_beagle_lcd_device = { +- .name = "omap3beagle_lcd", +- .id = -1, +-}; +- +-static struct omap_lcd_config omap3_beagle_lcd_config __initdata = { +- .ctrl_name = "internal", +-}; +- + static struct regulator_consumer_supply beagle_vmmc1_supply = { + .supply = "vmmc", + }; +@@ -232,16 +323,6 @@ + .setup = beagle_twl_gpio_setup, + }; + +-static struct regulator_consumer_supply beagle_vdac_supply = { +- .supply = "vdac", +- .dev = &omap3_beagle_lcd_device.dev, +-}; +- +-static struct regulator_consumer_supply beagle_vdvi_supply = { +- .supply = "vdvi", +- .dev = &omap3_beagle_lcd_device.dev, +-}; +- + /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ + static struct regulator_init_data beagle_vmmc1 = { + .constraints = { +@@ -419,14 +500,8 @@ + }, + }; + +-static struct omap_board_config_kernel omap3_beagle_config[] __initdata = { +- { OMAP_TAG_LCD, &omap3_beagle_lcd_config }, +-}; +- + static void __init omap3_beagle_init_irq(void) + { +- omap_board_config = omap3_beagle_config; +- omap_board_config_size = ARRAY_SIZE(omap3_beagle_config); + omap2_init_common_hw(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); + omap_init_irq(); +@@ -437,9 +512,9 @@ + } + + static struct platform_device *omap3_beagle_devices[] __initdata = { +- &omap3_beagle_lcd_device, + &leds_gpio, + &keys_gpio, ++ &beagle_dss_device, + }; + + static void __init omap3beagle_flash_init(void) +@@ -522,8 +597,9 @@ + /* Ensure SDRC pins are mux'd for self-refresh */ + omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); + omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT); +-} + ++ beagle_display_init(); ++} + static void __init omap3_beagle_map_io(void) + { + omap2_set_globals_343x(); diff --git a/recipes/linux/linux-omap-2.6.32/dss2/0016-video-add-timings-for-hd720.patch b/recipes/linux/linux-omap-2.6.32/dss2/0016-video-add-timings-for-hd720.patch new file mode 100644 index 0000000000..e5f7a4e072 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/dss2/0016-video-add-timings-for-hd720.patch @@ -0,0 +1,27 @@ +From 77c7ed5e802e9bb244cd00fa60c95de1e28c29be Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Sat, 19 Dec 2009 06:52:43 -0800 +Subject: [PATCH 16/16] video: add timings for hd720 + +--- + drivers/video/modedb.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c +index 34e4e79..9d9114d 100644 +--- a/drivers/video/modedb.c ++++ b/drivers/video/modedb.c +@@ -100,6 +100,10 @@ static const struct fb_videomode modedb[] = { + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, + 0, FB_VMODE_NONINTERLACED + }, { ++ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */ ++ "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5, ++ 0, FB_VMODE_NONINTERLACED ++ }, { + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, + 0, FB_VMODE_INTERLACED +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/madc/0009-drivers-mfd-add-twl4030-madc-driver.patch b/recipes/linux/linux-omap-2.6.32/madc/0009-drivers-mfd-add-twl4030-madc-driver.patch new file mode 100644 index 0000000000..00d7b9b72d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/madc/0009-drivers-mfd-add-twl4030-madc-driver.patch @@ -0,0 +1,601 @@ +From acfc350552bbe07f5dd8bf2e4f1db67af64975a8 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 14:19:34 -0800 +Subject: [PATCH 09/16] drivers: mfd: add twl4030 madc driver + +--- + drivers/mfd/Kconfig | 21 ++ + drivers/mfd/Makefile | 1 + + drivers/mfd/twl4030-madc.c | 536 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 558 insertions(+), 0 deletions(-) + create mode 100644 drivers/mfd/twl4030-madc.c + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 08f2d07..008ced0 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -127,6 +127,27 @@ config TWL4030_CODEC + select MFD_CORE + default n + ++config TWL4030_MADC ++ tristate "TWL4030 MADC Driver" ++ depends on TWL4030_CORE ++ help ++ The TWL4030 Monitoring ADC driver enables the host ++ processor to monitor analog signals using analog-to-digital ++ conversions on the input source. TWL4030 MADC provides the ++ following features: ++ - Single 10-bit ADC with successive approximation register (SAR) conversion; ++ - Analog multiplexer for 16 inputs; ++ - Seven (of the 16) inputs are freely available; ++ - Battery voltage monitoring; ++ - Concurrent conversion request management; ++ - Interrupt signal to Primary Interrupt Handler; ++ - Averaging feature; ++ - Selective enable/disable of the averaging feature. ++ ++ Say 'y' here to statically link this module into the kernel or 'm' ++ to build it as a dinamically loadable module. The module will be ++ called twl4030-madc.ko ++ + config MFD_TMIO + bool + default n +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index af0fc90..3992aee 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -27,6 +27,7 @@ obj-$(CONFIG_MENELAUS) += menelaus.o + obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o twl4030-irq.o + obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o + obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o ++obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o + + obj-$(CONFIG_MFD_MC13783) += mc13783-core.o + +diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c +new file mode 100644 +index 0000000..7d83ab8 +--- /dev/null ++++ b/drivers/mfd/twl4030-madc.c +@@ -0,0 +1,536 @@ ++/* ++ * TWL4030 MADC module driver ++ * ++ * Copyright (C) 2008 Nokia Corporation ++ * Mikko Ylinen <mikko.k.ylinen@nokia.com> ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ */ ++ ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/module.h> ++#include <linux/delay.h> ++#include <linux/fs.h> ++#include <linux/platform_device.h> ++#include <linux/miscdevice.h> ++#include <linux/i2c/twl4030.h> ++#include <linux/i2c/twl4030-madc.h> ++ ++#include <asm/uaccess.h> ++ ++#define TWL4030_MADC_PFX "twl4030-madc: " ++ ++struct twl4030_madc_data { ++ struct device *dev; ++ struct mutex lock; ++ struct work_struct ws; ++ struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS]; ++ int imr; ++ int isr; ++}; ++ ++static struct twl4030_madc_data *the_madc; ++ ++static ++const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = { ++ [TWL4030_MADC_RT] = { ++ .sel = TWL4030_MADC_RTSELECT_LSB, ++ .avg = TWL4030_MADC_RTAVERAGE_LSB, ++ .rbase = TWL4030_MADC_RTCH0_LSB, ++ }, ++ [TWL4030_MADC_SW1] = { ++ .sel = TWL4030_MADC_SW1SELECT_LSB, ++ .avg = TWL4030_MADC_SW1AVERAGE_LSB, ++ .rbase = TWL4030_MADC_GPCH0_LSB, ++ .ctrl = TWL4030_MADC_CTRL_SW1, ++ }, ++ [TWL4030_MADC_SW2] = { ++ .sel = TWL4030_MADC_SW2SELECT_LSB, ++ .avg = TWL4030_MADC_SW2AVERAGE_LSB, ++ .rbase = TWL4030_MADC_GPCH0_LSB, ++ .ctrl = TWL4030_MADC_CTRL_SW2, ++ }, ++}; ++ ++static int twl4030_madc_read(struct twl4030_madc_data *madc, u8 reg) ++{ ++ int ret; ++ u8 val; ++ ++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MADC, &val, reg); ++ if (ret) { ++ dev_dbg(madc->dev, "unable to read register 0x%X\n", reg); ++ return ret; ++ } ++ ++ return val; ++} ++ ++static void twl4030_madc_write(struct twl4030_madc_data *madc, u8 reg, u8 val) ++{ ++ int ret; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MADC, val, reg); ++ if (ret) ++ dev_err(madc->dev, "unable to write register 0x%X\n", reg); ++} ++ ++static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg) ++{ ++ u8 msb, lsb; ++ ++ /* For each ADC channel, we have MSB and LSB register pair. MSB address ++ * is always LSB address+1. reg parameter is the addr of LSB register */ ++ msb = twl4030_madc_read(madc, reg + 1); ++ lsb = twl4030_madc_read(madc, reg); ++ ++ return (int)(((msb << 8) | lsb) >> 6); ++} ++ ++static int twl4030_madc_read_channels(struct twl4030_madc_data *madc, ++ u8 reg_base, u16 channels, int *buf) ++{ ++ int count = 0; ++ u8 reg, i; ++ ++ if (unlikely(!buf)) ++ return 0; ++ ++ for (i = 0; i < TWL4030_MADC_MAX_CHANNELS; i++) { ++ if (channels & (1<<i)) { ++ reg = reg_base + 2*i; ++ buf[i] = twl4030_madc_channel_raw_read(madc, reg); ++ count++; ++ } ++ } ++ return count; ++} ++ ++static void twl4030_madc_enable_irq(struct twl4030_madc_data *madc, int id) ++{ ++ u8 val; ++ ++ val = twl4030_madc_read(madc, madc->imr); ++ val &= ~(1 << id); ++ twl4030_madc_write(madc, madc->imr, val); ++} ++ ++static void twl4030_madc_disable_irq(struct twl4030_madc_data *madc, int id) ++{ ++ u8 val; ++ ++ val = twl4030_madc_read(madc, madc->imr); ++ val |= (1 << id); ++ twl4030_madc_write(madc, madc->imr, val); ++} ++ ++static irqreturn_t twl4030_madc_irq_handler(int irq, void *_madc) ++{ ++ struct twl4030_madc_data *madc = _madc; ++ u8 isr_val, imr_val; ++ int i; ++ ++#ifdef CONFIG_LOCKDEP ++ /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which ++ * we don't want and can't tolerate. Although it might be ++ * friendlier not to borrow this thread context... ++ */ ++ local_irq_enable(); ++#endif ++ ++ /* Use COR to ack interrupts since we have no shared IRQs in ISRx */ ++ isr_val = twl4030_madc_read(madc, madc->isr); ++ imr_val = twl4030_madc_read(madc, madc->imr); ++ ++ isr_val &= ~imr_val; ++ ++ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { ++ ++ if (!(isr_val & (1<<i))) ++ continue; ++ ++ twl4030_madc_disable_irq(madc, i); ++ madc->requests[i].result_pending = 1; ++ } ++ ++ schedule_work(&madc->ws); ++ ++ return IRQ_HANDLED; ++} ++ ++static void twl4030_madc_work(struct work_struct *ws) ++{ ++ const struct twl4030_madc_conversion_method *method; ++ struct twl4030_madc_data *madc; ++ struct twl4030_madc_request *r; ++ int len, i; ++ ++ madc = container_of(ws, struct twl4030_madc_data, ws); ++ mutex_lock(&madc->lock); ++ ++ for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { ++ ++ r = &madc->requests[i]; ++ ++ /* No pending results for this method, move to next one */ ++ if (!r->result_pending) ++ continue; ++ ++ method = &twl4030_conversion_methods[r->method]; ++ ++ /* Read results */ ++ len = twl4030_madc_read_channels(madc, method->rbase, ++ r->channels, r->rbuf); ++ ++ /* Return results to caller */ ++ if (r->func_cb != NULL) { ++ r->func_cb(len, r->channels, r->rbuf); ++ r->func_cb = NULL; ++ } ++ ++ /* Free request */ ++ r->result_pending = 0; ++ r->active = 0; ++ } ++ ++ mutex_unlock(&madc->lock); ++} ++ ++static int twl4030_madc_set_irq(struct twl4030_madc_data *madc, ++ struct twl4030_madc_request *req) ++{ ++ struct twl4030_madc_request *p; ++ ++ p = &madc->requests[req->method]; ++ ++ memcpy(p, req, sizeof *req); ++ ++ twl4030_madc_enable_irq(madc, req->method); ++ ++ return 0; ++} ++ ++static inline void twl4030_madc_start_conversion(struct twl4030_madc_data *madc, ++ int conv_method) ++{ ++ const struct twl4030_madc_conversion_method *method; ++ ++ method = &twl4030_conversion_methods[conv_method]; ++ ++ switch (conv_method) { ++ case TWL4030_MADC_SW1: ++ case TWL4030_MADC_SW2: ++ twl4030_madc_write(madc, method->ctrl, TWL4030_MADC_SW_START); ++ break; ++ case TWL4030_MADC_RT: ++ default: ++ break; ++ } ++} ++ ++static int twl4030_madc_wait_conversion_ready( ++ struct twl4030_madc_data *madc, ++ unsigned int timeout_ms, u8 status_reg) ++{ ++ unsigned long timeout; ++ ++ timeout = jiffies + msecs_to_jiffies(timeout_ms); ++ do { ++ u8 reg; ++ ++ reg = twl4030_madc_read(madc, status_reg); ++ if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW)) ++ return 0; ++ } while (!time_after(jiffies, timeout)); ++ ++ return -EAGAIN; ++} ++ ++int twl4030_madc_conversion(struct twl4030_madc_request *req) ++{ ++ const struct twl4030_madc_conversion_method *method; ++ u8 ch_msb, ch_lsb; ++ int ret; ++ ++ if (unlikely(!req)) ++ return -EINVAL; ++ ++ mutex_lock(&the_madc->lock); ++ ++ /* Do we have a conversion request ongoing */ ++ if (the_madc->requests[req->method].active) { ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ ch_msb = (req->channels >> 8) & 0xff; ++ ch_lsb = req->channels & 0xff; ++ ++ method = &twl4030_conversion_methods[req->method]; ++ ++ /* Select channels to be converted */ ++ twl4030_madc_write(the_madc, method->sel + 1, ch_msb); ++ twl4030_madc_write(the_madc, method->sel, ch_lsb); ++ ++ /* Select averaging for all channels if do_avg is set */ ++ if (req->do_avg) { ++ twl4030_madc_write(the_madc, method->avg + 1, ch_msb); ++ twl4030_madc_write(the_madc, method->avg, ch_lsb); ++ } ++ ++ if ((req->type == TWL4030_MADC_IRQ_ONESHOT) && (req->func_cb != NULL)) { ++ twl4030_madc_set_irq(the_madc, req); ++ twl4030_madc_start_conversion(the_madc, req->method); ++ the_madc->requests[req->method].active = 1; ++ ret = 0; ++ goto out; ++ } ++ ++ /* With RT method we should not be here anymore */ ++ if (req->method == TWL4030_MADC_RT) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ twl4030_madc_start_conversion(the_madc, req->method); ++ the_madc->requests[req->method].active = 1; ++ ++ /* Wait until conversion is ready (ctrl register returns EOC) */ ++ ret = twl4030_madc_wait_conversion_ready(the_madc, 5, method->ctrl); ++ if (ret) { ++ dev_dbg(the_madc->dev, "conversion timeout!\n"); ++ the_madc->requests[req->method].active = 0; ++ goto out; ++ } ++ ++ ret = twl4030_madc_read_channels(the_madc, method->rbase, req->channels, ++ req->rbuf); ++ ++ the_madc->requests[req->method].active = 0; ++ ++out: ++ mutex_unlock(&the_madc->lock); ++ ++ return ret; ++} ++EXPORT_SYMBOL(twl4030_madc_conversion); ++ ++static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc, ++ int chan, int on) ++{ ++ int ret; ++ u8 regval; ++ ++ /* Current generator is only available for ADCIN0 and ADCIN1. NB: ++ * ADCIN1 current generator only works when AC or VBUS is present */ ++ if (chan > 1) ++ return EINVAL; ++ ++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, ++ ®val, TWL4030_BCI_BCICTL1); ++ if (on) ++ regval |= (chan) ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN; ++ else ++ regval &= (chan) ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN; ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, ++ regval, TWL4030_BCI_BCICTL1); ++ ++ return ret; ++} ++ ++static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on) ++{ ++ u8 regval; ++ ++ regval = twl4030_madc_read(madc, TWL4030_MADC_CTRL1); ++ if (on) ++ regval |= TWL4030_MADC_MADCON; ++ else ++ regval &= ~TWL4030_MADC_MADCON; ++ twl4030_madc_write(madc, TWL4030_MADC_CTRL1, regval); ++ ++ return 0; ++} ++ ++static long twl4030_madc_ioctl(struct file *filp, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct twl4030_madc_user_parms par; ++ int val, ret; ++ ++ ret = copy_from_user(&par, (void __user *) arg, sizeof(par)); ++ if (ret) { ++ dev_dbg(the_madc->dev, "copy_from_user: %d\n", ret); ++ return -EACCES; ++ } ++ ++ switch (cmd) { ++ case TWL4030_MADC_IOCX_ADC_RAW_READ: { ++ struct twl4030_madc_request req; ++ if (par.channel >= TWL4030_MADC_MAX_CHANNELS) ++ return -EINVAL; ++ ++ req.channels = (1 << par.channel); ++ req.do_avg = par.average; ++ req.method = TWL4030_MADC_SW1; ++ req.func_cb = NULL; ++ ++ val = twl4030_madc_conversion(&req); ++ if (val <= 0) { ++ par.status = -1; ++ } else { ++ par.status = 0; ++ par.result = (u16)req.rbuf[par.channel]; ++ } ++ break; ++ } ++ default: ++ return -EINVAL; ++ } ++ ++ ret = copy_to_user((void __user *) arg, &par, sizeof(par)); ++ if (ret) { ++ dev_dbg(the_madc->dev, "copy_to_user: %d\n", ret); ++ return -EACCES; ++ } ++ ++ return 0; ++} ++ ++static struct file_operations twl4030_madc_fileops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = twl4030_madc_ioctl ++}; ++ ++static struct miscdevice twl4030_madc_device = { ++ .minor = MISC_DYNAMIC_MINOR, ++ .name = "twl4030-madc", ++ .fops = &twl4030_madc_fileops ++}; ++ ++static int __init twl4030_madc_probe(struct platform_device *pdev) ++{ ++ struct twl4030_madc_data *madc; ++ struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data; ++ int ret; ++ u8 regval; ++ ++ madc = kzalloc(sizeof *madc, GFP_KERNEL); ++ if (!madc) ++ return -ENOMEM; ++ ++ if (!pdata) { ++ dev_dbg(&pdev->dev, "platform_data not available\n"); ++ ret = -EINVAL; ++ goto err_pdata; ++ } ++ ++ madc->imr = (pdata->irq_line == 1) ? TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2; ++ madc->isr = (pdata->irq_line == 1) ? TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2; ++ ++ ret = misc_register(&twl4030_madc_device); ++ if (ret) { ++ dev_dbg(&pdev->dev, "could not register misc_device\n"); ++ goto err_misc; ++ } ++ twl4030_madc_set_power(madc, 1); ++ twl4030_madc_set_current_generator(madc, 0, 1); ++ ++ /* Enable ADCIN3 through 6 */ ++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_USB, ++ ®val, TWL4030_USB_CARKIT_ANA_CTRL); ++ ++ regval |= TWL4030_USB_SEL_MADC_MCPC; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_USB, ++ regval, TWL4030_USB_CARKIT_ANA_CTRL); ++ ++ ++ ret = twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, ++ ®val, TWL4030_BCI_BCICTL1); ++ ++ regval |= TWL4030_BCI_MESBAT; ++ ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, ++ regval, TWL4030_BCI_BCICTL1); ++ ++ ret = request_irq(platform_get_irq(pdev, 0), twl4030_madc_irq_handler, ++ 0, "twl4030_madc", madc); ++ if (ret) { ++ dev_dbg(&pdev->dev, "could not request irq\n"); ++ goto err_irq; ++ } ++ ++ platform_set_drvdata(pdev, madc); ++ mutex_init(&madc->lock); ++ INIT_WORK(&madc->ws, twl4030_madc_work); ++ ++ the_madc = madc; ++ ++ return 0; ++ ++err_irq: ++ misc_deregister(&twl4030_madc_device); ++ ++err_misc: ++err_pdata: ++ kfree(madc); ++ ++ return ret; ++} ++ ++static int __exit twl4030_madc_remove(struct platform_device *pdev) ++{ ++ struct twl4030_madc_data *madc = platform_get_drvdata(pdev); ++ ++ twl4030_madc_set_power(madc, 0); ++ twl4030_madc_set_current_generator(madc, 0, 0); ++ free_irq(platform_get_irq(pdev, 0), madc); ++ cancel_work_sync(&madc->ws); ++ misc_deregister(&twl4030_madc_device); ++ ++ return 0; ++} ++ ++static struct platform_driver twl4030_madc_driver = { ++ .probe = twl4030_madc_probe, ++ .remove = __exit_p(twl4030_madc_remove), ++ .driver = { ++ .name = "twl4030_madc", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init twl4030_madc_init(void) ++{ ++ return platform_driver_register(&twl4030_madc_driver); ++} ++module_init(twl4030_madc_init); ++ ++static void __exit twl4030_madc_exit(void) ++{ ++ platform_driver_unregister(&twl4030_madc_driver); ++} ++module_exit(twl4030_madc_exit); ++ ++MODULE_ALIAS("platform:twl4030-madc"); ++MODULE_AUTHOR("Nokia Corporation"); ++MODULE_DESCRIPTION("twl4030 ADC driver"); ++MODULE_LICENSE("GPL"); ++ +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/madc/0010-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch b/recipes/linux/linux-omap-2.6.32/madc/0010-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch new file mode 100644 index 0000000000..3b5164c8e7 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/madc/0010-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch @@ -0,0 +1,32 @@ +From a7e4d5c1b598e866c98be33768d14c9cd80d864d Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 14:27:15 -0800 +Subject: [PATCH 10/16] ARM: OMAP: Add twl4030 madc support to Overo + +--- + arch/arm/mach-omap2/board-overo.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c +index 1b94f2c..d0394d9 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -390,10 +390,15 @@ static struct twl4030_codec_data overo_codec_data = { + + /* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ + ++static struct twl4030_madc_platform_data overo_madc_data = { ++ .irq_line = 1, ++}; ++ + static struct twl4030_platform_data overo_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + .gpio = &overo_gpio_data, ++ .madc = &overo_madc_data, + .usb = &overo_usb_data, + .codec = &overo_codec_data, + .vmmc1 = &overo_vmmc1, +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/madc/0011-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch b/recipes/linux/linux-omap-2.6.32/madc/0011-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch new file mode 100644 index 0000000000..cba908fb3c --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/madc/0011-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch @@ -0,0 +1,35 @@ +From 1a123bfff816abb027985923799c3e448e5cb7b7 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 14:32:36 -0800 +Subject: [PATCH 11/16] ARM: OMAP: Add twl4030 madc support to Beagle + +--- + arch/arm/mach-omap2/board-omap3beagle.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index d00b089..955da5b 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -314,6 +314,10 @@ static struct twl4030_codec_data beagle_codec_data = { + .audio = &beagle_audio_data, + }; + ++static struct twl4030_madc_platform_data beagle_madc_data = { ++ .irq_line = 1, ++}; ++ + static struct twl4030_platform_data beagle_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, +@@ -322,6 +326,7 @@ static struct twl4030_platform_data beagle_twldata = { + .usb = &beagle_usb_data, + .gpio = &beagle_gpio_data, + .codec = &beagle_codec_data, ++ .madc = &beagle_madc_data, + .vmmc1 = &beagle_vmmc1, + .vsim = &beagle_vsim, + .vdac = &beagle_vdac, +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap-2.6.32/madc/0013-ARM-OMAP-Add-missing-twl4030-madc-header-file.patch b/recipes/linux/linux-omap-2.6.32/madc/0013-ARM-OMAP-Add-missing-twl4030-madc-header-file.patch new file mode 100644 index 0000000000..b021871993 --- /dev/null +++ b/recipes/linux/linux-omap-2.6.32/madc/0013-ARM-OMAP-Add-missing-twl4030-madc-header-file.patch @@ -0,0 +1,149 @@ +From c7412fa6dec1460ac0d1895f16421732e5174406 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 17 Dec 2009 15:54:58 -0800 +Subject: [PATCH 13/16] ARM: OMAP: Add missing twl4030 madc header file + +--- + include/linux/i2c/twl4030-madc.h | 130 ++++++++++++++++++++++++++++++++++++++ + 1 files changed, 130 insertions(+), 0 deletions(-) + create mode 100644 include/linux/i2c/twl4030-madc.h + +diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h +new file mode 100644 +index 0000000..341a665 +--- /dev/null ++++ b/include/linux/i2c/twl4030-madc.h +@@ -0,0 +1,130 @@ ++/* ++ * include/linux/i2c/twl4030-madc.h ++ * ++ * TWL4030 MADC module driver header ++ * ++ * Copyright (C) 2008 Nokia Corporation ++ * Mikko Ylinen <mikko.k.ylinen@nokia.com> ++ * ++ * 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. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ */ ++ ++#ifndef _TWL4030_MADC_H ++#define _TWL4030_MADC_H ++ ++struct twl4030_madc_conversion_method { ++ u8 sel; ++ u8 avg; ++ u8 rbase; ++ u8 ctrl; ++}; ++ ++#define TWL4030_MADC_MAX_CHANNELS 16 ++ ++struct twl4030_madc_request { ++ u16 channels; ++ u16 do_avg; ++ u16 method; ++ u16 type; ++ int active; ++ int result_pending; ++ int rbuf[TWL4030_MADC_MAX_CHANNELS]; ++ void (*func_cb)(int len, int channels, int *buf); ++}; ++ ++enum conversion_methods { ++ TWL4030_MADC_RT, ++ TWL4030_MADC_SW1, ++ TWL4030_MADC_SW2, ++ TWL4030_MADC_NUM_METHODS ++}; ++ ++enum sample_type { ++ TWL4030_MADC_WAIT, ++ TWL4030_MADC_IRQ_ONESHOT, ++ TWL4030_MADC_IRQ_REARM ++}; ++ ++#define TWL4030_MADC_CTRL1 0x00 ++#define TWL4030_MADC_CTRL2 0x01 ++ ++#define TWL4030_MADC_RTSELECT_LSB 0x02 ++#define TWL4030_MADC_SW1SELECT_LSB 0x06 ++#define TWL4030_MADC_SW2SELECT_LSB 0x0A ++ ++#define TWL4030_MADC_RTAVERAGE_LSB 0x04 ++#define TWL4030_MADC_SW1AVERAGE_LSB 0x08 ++#define TWL4030_MADC_SW2AVERAGE_LSB 0x0C ++ ++#define TWL4030_MADC_CTRL_SW1 0x12 ++#define TWL4030_MADC_CTRL_SW2 0x13 ++ ++#define TWL4030_MADC_RTCH0_LSB 0x17 ++#define TWL4030_MADC_GPCH0_LSB 0x37 ++ ++#define TWL4030_MADC_MADCON (1<<0) /* MADC power on */ ++#define TWL4030_MADC_BUSY (1<<0) /* MADC busy */ ++#define TWL4030_MADC_EOC_SW (1<<1) /* MADC conversion completion */ ++#define TWL4030_MADC_SW_START (1<<5) /* MADC SWx start conversion */ ++ ++#define TWL4030_MADC_ADCIN0 (1<<0) ++#define TWL4030_MADC_ADCIN1 (1<<1) ++#define TWL4030_MADC_ADCIN2 (1<<2) ++#define TWL4030_MADC_ADCIN3 (1<<3) ++#define TWL4030_MADC_ADCIN4 (1<<4) ++#define TWL4030_MADC_ADCIN5 (1<<5) ++#define TWL4030_MADC_ADCIN6 (1<<6) ++#define TWL4030_MADC_ADCIN7 (1<<7) ++#define TWL4030_MADC_ADCIN8 (1<<8) ++#define TWL4030_MADC_ADCIN9 (1<<9) ++#define TWL4030_MADC_ADCIN10 (1<<10) ++#define TWL4030_MADC_ADCIN11 (1<<11) ++#define TWL4030_MADC_ADCIN12 (1<<12) ++#define TWL4030_MADC_ADCIN13 (1<<13) ++#define TWL4030_MADC_ADCIN14 (1<<14) ++#define TWL4030_MADC_ADCIN15 (1<<15) ++ ++/* Fixed channels */ ++#define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1 ++#define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8 ++#define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9 ++#define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10 ++#define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11 ++#define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12 ++ ++/* BCI related - XXX To be moved elsewhere */ ++#define TWL4030_BCI_BCICTL1 0x23 ++#define TWL4030_BCI_MESBAT (1<<1) ++#define TWL4030_BCI_TYPEN (1<<4) ++#define TWL4030_BCI_ITHEN (1<<3) ++ ++/* USB related - XXX To be moved elsewhere */ ++#define TWL4030_USB_CARKIT_ANA_CTRL 0xBB ++#define TWL4030_USB_SEL_MADC_MCPC (1<<3) ++ ++#define TWL4030_MADC_IOC_MAGIC '`' ++#define TWL4030_MADC_IOCX_ADC_RAW_READ _IO(TWL4030_MADC_IOC_MAGIC, 0) ++ ++struct twl4030_madc_user_parms { ++ int channel; ++ int average; ++ int status; ++ u16 result; ++}; ++ ++int twl4030_madc_conversion(struct twl4030_madc_request *conv); ++ ++#endif +-- +1.6.2.4 + diff --git a/recipes/linux/linux-omap_2.6.32.bb b/recipes/linux/linux-omap_2.6.32.bb index 3eff244391..f8472b3a21 100644 --- a/recipes/linux/linux-omap_2.6.32.bb +++ b/recipes/linux/linux-omap_2.6.32.bb @@ -23,7 +23,20 @@ file://cm-t35/0001-OMAP-DSS2-add-Toppoly-TDO35S-panel.patch;patch=1 \ file://cm-t35/0002-omap3-cm-t35-add-DSS2-display-support.patch;patch=1 \ file://cm-t35/0003-omap3-cm-t35-update-defconfig-for-DSS2.patch;patch=1 \ file://cm-t35/0006-omap3-cm-t35-update-defconfig.patch;patch=1 \ -file://dss2/beagle-dss2-support.diff;patch=1 \ +file://0001-ARM-OMAP-Overo-Add-support-for-second-ethernet-po.patch;patch=1 \ +file://0003-drivers-net-smsc911x-return-ENODEV-if-device-is-n.patch;patch=1 \ +file://0004-drivers-input-touchscreen-ads7846-return-ENODEV.patch;patch=1 \ +file://0005-ARM-OMAP-add-support-for-TCT-Zippy-to-Beagle-board.patch;patch=1 \ +file://0006-ARM-OMAP-Make-beagle-u-boot-partition-writable.patch;patch=1 \ +file://0007-ASoC-enable-audio-capture-by-default-for-twl4030.patch;patch=1 \ +file://madc/0009-drivers-mfd-add-twl4030-madc-driver.patch;patch=1 \ +file://madc/0010-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch;patch=1 \ +file://madc/0011-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch;patch=1 \ +file://madc/0013-ARM-OMAP-Add-missing-twl4030-madc-header-file.patch;patch=1 \ +file://dss2/0012-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-pane.patch;patch=1 \ +#file://dss2/0014-OMAP-DSS-Add-DSS2-support-for-Overo.patch;patch=1 \ +file://dss2/0015-OMAP-DSS-Add-DSS2-support-for-Beagle.patch;patch=1 \ +file://dss2/0016-video-add-timings-for-hd720.patch;patch=1 \ " SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \ |