From 88867c1d96684925027a0ecc9e25c6ea70040cc6 Mon Sep 17 00:00:00 2001 From: Denys Dmytriyenko Date: Mon, 11 Jun 2012 20:44:56 -0400 Subject: extras: move things to extras Move non-essential, outdated, best-effort pieces, as well, as those requiring extra non-standard dependencies besides oe-core. Signed-off-by: Denys Dmytriyenko --- ...omap3-beaglexm-fix-EHCI-power-up-GPIO-dir.patch | 44 ++ .../0002-omap3-beaglexm-fix-DVI-reset-GPIO.patch | 48 ++ .../0003-omap3-beaglexm-fix-power-on-of-DVI.patch | 94 +++ ...0004-omap-Beagle-detect-new-xM-revision-B.patch | 43 ++ ...agleboard-Add-infrastructure-to-do-fixups.patch | 219 ++++++ ...agleboard-pre-export-GPIOs-to-userspace-w.patch | 57 ++ .../0007-modedb.c-add-proper-720p60-mode.patch | 28 + ...isplay-single-block-read-console-messages.patch | 28 + .../0009-MTD-silence-ecc-errors-on-mtdblock0.patch | 63 ++ .../linux/linux-omap/base/0010-Miracle-patch.patch | 504 ++++++++++++++ .../base/0011-ARM-OMAP-add-omap_rev_-macros.patch | 81 +++ ...enable-hsclk-in-dsi_pll_init-for-OMAP36XX.patch | 31 + ...eboard-add-WIP-support-for-beagleboardtoy.patch | 128 ++++ ...-smsc911x-return-ENODEV-if-device-is-not-.patch | 29 + ...ut-touchscreen-ads7846-return-ENODEV-if-d.patch | 47 ++ ...able-audio-capture-by-default-for-twl4030.patch | 27 + .../base/0017-MFD-enable-madc-clock.patch | 51 ++ .../base/0018-MFD-add-twl4030-madc-driver.patch | 740 +++++++++++++++++++++ ...RM-OMAP-Add-twl4030-madc-support-to-Overo.patch | 32 + ...M-OMAP-Add-twl4030-madc-support-to-Beagle.patch | 35 + ...dd-support-for-Samsung-LTE430WQ-F0C-panel.patch | 173 +++++ ...Add-support-for-LG-Philips-LB035Q02-panel.patch | 299 +++++++++ ...dd-bootarg-for-selecting-svideo-or-compos.patch | 75 +++ ...mc-twl4030-move-clock-input-selection-pri.patch | 39 ++ ...C-add-support-for-backup-battery-recharge.patch | 55 ++ ...tomatically-set-musb-mode-in-platform-dat.patch | 49 ++ ...heck-for-both-cpu-type-and-revision-rathe.patch | 34 + ...0028-OMAP-DSS2-Add-DSS2-support-for-Overo.patch | 355 ++++++++++ 28 files changed, 3408 insertions(+) create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0001-omap3-beaglexm-fix-EHCI-power-up-GPIO-dir.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0002-omap3-beaglexm-fix-DVI-reset-GPIO.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0003-omap3-beaglexm-fix-power-on-of-DVI.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0004-omap-Beagle-detect-new-xM-revision-B.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0005-ARM-OMAP-beagleboard-Add-infrastructure-to-do-fixups.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0006-ARM-OMAP-beagleboard-pre-export-GPIOs-to-userspace-w.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0007-modedb.c-add-proper-720p60-mode.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0008-mmc-don-t-display-single-block-read-console-messages.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0009-MTD-silence-ecc-errors-on-mtdblock0.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0010-Miracle-patch.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0011-ARM-OMAP-add-omap_rev_-macros.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0012-OMAP-DSS2-enable-hsclk-in-dsi_pll_init-for-OMAP36XX.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0013-omap3-beagleboard-add-WIP-support-for-beagleboardtoy.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0014-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0015-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0016-ASoC-enable-audio-capture-by-default-for-twl4030.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0017-MFD-enable-madc-clock.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0018-MFD-add-twl4030-madc-driver.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0020-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0021-OMAP-DSS2-Add-support-for-Samsung-LTE430WQ-F0C-panel.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0022-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-panel.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0023-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0024-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0025-RTC-add-support-for-backup-battery-recharge.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0026-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0027-OMAP-DSS2-check-for-both-cpu-type-and-revision-rathe.patch create mode 100644 extras/recipes-kernel/linux/linux-omap/base/0028-OMAP-DSS2-Add-DSS2-support-for-Overo.patch (limited to 'extras/recipes-kernel/linux/linux-omap/base') diff --git a/extras/recipes-kernel/linux/linux-omap/base/0001-omap3-beaglexm-fix-EHCI-power-up-GPIO-dir.patch b/extras/recipes-kernel/linux/linux-omap/base/0001-omap3-beaglexm-fix-EHCI-power-up-GPIO-dir.patch new file mode 100644 index 00000000..42bfa4e2 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0001-omap3-beaglexm-fix-EHCI-power-up-GPIO-dir.patch @@ -0,0 +1,44 @@ +From 3d2f0e2f29320d9c6a6e4d8d5aeff9127a2106cb Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Tue, 11 Jan 2011 17:13:35 +0000 +Subject: [PATCH 01/28] omap3: beaglexm: fix EHCI power up GPIO dir + +EHCI enable power pin is inverted (active high) in comparison +to vanilla beagle which is active low. Handle this case conditionally. + +Without this fix, Beagle XM 4 port EHCI will not function and no +networking will be available + +[nm@ti.com: split up, added descriptive changelogs] +Signed-off-by: Nishanth Menon +Signed-off-by: Koen Kooi +Signed-off-by: Tony Lindgren +--- + arch/arm/mach-omap2/board-omap3beagle.c | 10 ++++++++-- + 1 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 6c12760..af1166b 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -297,9 +297,15 @@ static int beagle_twl_gpio_setup(struct device *dev, + gpio_request(gpio + 1, "EHCI_nOC"); + gpio_direction_input(gpio + 1); + +- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */ ++ /* ++ * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active ++ * high / others active low) ++ */ + gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR"); +- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); ++ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) ++ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1); ++ else ++ gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0002-omap3-beaglexm-fix-DVI-reset-GPIO.patch b/extras/recipes-kernel/linux/linux-omap/base/0002-omap3-beaglexm-fix-DVI-reset-GPIO.patch new file mode 100644 index 00000000..1808a861 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0002-omap3-beaglexm-fix-DVI-reset-GPIO.patch @@ -0,0 +1,48 @@ +From e1dd1afba99853083da545f632a1f7c6899ae379 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Tue, 11 Jan 2011 17:13:36 +0000 +Subject: [PATCH 02/28] omap3: beaglexm: fix DVI reset GPIO + +GPIO reset line for Beagle XM is different from vanilla beagle +so we populate it as part of gpio update routine. + +This in part fixes the issue of display not functioning on beagle XM +platform. + +[nm@ti.com: split up, added descriptive changelogs] +Signed-off-by: Nishanth Menon +Signed-off-by: Koen Kooi +Signed-off-by: Tony Lindgren +--- + arch/arm/mach-omap2/board-omap3beagle.c | 8 +++++++- + 1 files changed, 7 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index af1166b..673deb9 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -199,7 +199,7 @@ static struct omap_dss_device beagle_dvi_device = { + .name = "dvi", + .driver_name = "generic_panel", + .phy.dpi.data_lines = 24, +- .reset_gpio = 170, ++ .reset_gpio = -EINVAL, + .platform_enable = beagle_enable_dvi, + .platform_disable = beagle_disable_dvi, + }; +@@ -307,6 +307,12 @@ static int beagle_twl_gpio_setup(struct device *dev, + else + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + ++ /* DVI reset GPIO is different between beagle revisions */ ++ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) ++ beagle_dvi_device.reset_gpio = 129; ++ else ++ beagle_dvi_device.reset_gpio = 170; ++ + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0003-omap3-beaglexm-fix-power-on-of-DVI.patch b/extras/recipes-kernel/linux/linux-omap/base/0003-omap3-beaglexm-fix-power-on-of-DVI.patch new file mode 100644 index 00000000..90446e40 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0003-omap3-beaglexm-fix-power-on-of-DVI.patch @@ -0,0 +1,94 @@ +From 4004c3e68b973f4cb736048b1e90ee3b511f5865 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Wed, 12 Jan 2011 00:23:29 +0000 +Subject: [PATCH 03/28] omap3: beaglexm: fix power on of DVI + +TFP410 DVI chip is used to provide display out. +This chip is controlled by 2 lines: +LDO which supplies the power is controlled over gpio + 2 +and the enable of the chip itself is done over gpio + 1 +NOTE: the LDO is necessary for LED, serial blocks as well. + +gpio + 1 was used to sense USB overcurrent in vanilla beagle. + +Without this fix, the display would not function as the LDO +remains shut down. + +[nm@ti.com: split up, added descriptive changelogs] +Signed-off-by: Nishanth Menon +Signed-off-by: Koen Kooi +Signed-off-by: Tony Lindgren +--- + arch/arm/mach-omap2/board-omap3beagle.c | 42 ++++++++++++++++++++++++++++-- + 1 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 673deb9..2ed8040 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -273,6 +273,8 @@ static struct gpio_led gpio_leds[]; + static int beagle_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) + { ++ int r; ++ + if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { + mmc[0].gpio_wp = -EINVAL; + } else if ((omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_C1_3) || +@@ -293,9 +295,16 @@ static int beagle_twl_gpio_setup(struct device *dev, + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ +- +- gpio_request(gpio + 1, "EHCI_nOC"); +- gpio_direction_input(gpio + 1); ++ if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) { ++ r = gpio_request(gpio + 1, "EHCI_nOC"); ++ if (!r) { ++ r = gpio_direction_input(gpio + 1); ++ if (r) ++ gpio_free(gpio + 1); ++ } ++ if (r) ++ pr_err("%s: unable to configure EHCI_nOC\n", __func__); ++ } + + /* + * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active +@@ -316,6 +325,33 @@ static int beagle_twl_gpio_setup(struct device *dev, + /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */ + gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1; + ++ /* ++ * gpio + 1 on Xm controls the TFP410's enable line (active low) ++ * gpio + 2 control varies depending on the board rev as follows: ++ * P7/P8 revisions(prototype): Camera EN ++ * A2+ revisions (production): LDO (supplies DVI, serial, led blocks) ++ */ ++ if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) { ++ r = gpio_request(gpio + 1, "nDVI_PWR_EN"); ++ if (!r) { ++ r = gpio_direction_output(gpio + 1, 0); ++ if (r) ++ gpio_free(gpio + 1); ++ } ++ if (r) ++ pr_err("%s: unable to configure nDVI_PWR_EN\n", ++ __func__); ++ r = gpio_request(gpio + 2, "DVI_LDO_EN"); ++ if (!r) { ++ r = gpio_direction_output(gpio + 2, 1); ++ if (r) ++ gpio_free(gpio + 2); ++ } ++ if (r) ++ pr_err("%s: unable to configure DVI_LDO_EN\n", ++ __func__); ++ } ++ + return 0; + } + +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0004-omap-Beagle-detect-new-xM-revision-B.patch b/extras/recipes-kernel/linux/linux-omap/base/0004-omap-Beagle-detect-new-xM-revision-B.patch new file mode 100644 index 00000000..43371618 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0004-omap-Beagle-detect-new-xM-revision-B.patch @@ -0,0 +1,43 @@ +From 24b7a742b27ed2c05c6bc7800b0299a77af37a82 Mon Sep 17 00:00:00 2001 +From: Robert Nelson +Date: Tue, 9 Nov 2010 08:34:55 -0600 +Subject: [PATCH 04/28] omap: Beagle: detect new xM revision B + +The xM B uses a DM3730 ES1.1 over the ES1.0 on xM A's, no other board changes. + +Signed-off-by: Robert Nelson +Signed-off-by: Koen Kooi +--- + arch/arm/mach-omap2/board-omap3beagle.c | 9 +++++++-- + 1 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 2ed8040..f9fb64b 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -58,7 +58,8 @@ + * AXBX = GPIO173, GPIO172, GPIO171: 1 1 1 + * C1_3 = GPIO173, GPIO172, GPIO171: 1 1 0 + * C4 = GPIO173, GPIO172, GPIO171: 1 0 1 +- * XM = GPIO173, GPIO172, GPIO171: 0 0 0 ++ * XMA = GPIO173, GPIO172, GPIO171: 0 0 0 ++ * XMB = GPIO173, GPIO172, GPIO171: 0 0 1 + */ + enum { + OMAP3BEAGLE_BOARD_UNKN = 0, +@@ -117,7 +118,11 @@ static void __init omap3_beagle_init_rev(void) + omap3_beagle_version = OMAP3BEAGLE_BOARD_C4; + break; + case 0: +- printk(KERN_INFO "OMAP3 Beagle Rev: xM\n"); ++ printk(KERN_INFO "OMAP3 Beagle Rev: xM A\n"); ++ omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; ++ break; ++ case 1: ++ printk(KERN_INFO "OMAP3 Beagle Rev: xM B\n"); + omap3_beagle_version = OMAP3BEAGLE_BOARD_XM; + break; + default: +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0005-ARM-OMAP-beagleboard-Add-infrastructure-to-do-fixups.patch b/extras/recipes-kernel/linux/linux-omap/base/0005-ARM-OMAP-beagleboard-Add-infrastructure-to-do-fixups.patch new file mode 100644 index 00000000..21d8d8fe --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0005-ARM-OMAP-beagleboard-Add-infrastructure-to-do-fixups.patch @@ -0,0 +1,219 @@ +From a564ca287c115928a9e7febf7c99bbab582290e6 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Wed, 6 Oct 2010 10:19:34 +0200 +Subject: [PATCH 05/28] ARM: OMAP: beagleboard: Add infrastructure to do fixups based on expansionboard name passed by u-boot + +Add support for Tincantools Zippy and Zippy2 expansionboards as well + +Signed-off-by: Koen Kooi +--- + arch/arm/mach-omap2/board-omap3beagle.c | 142 ++++++++++++++++++++++++++++++- + 1 files changed, 139 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index f9fb64b..d777b3b 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -143,6 +144,92 @@ fail0: + return; + } + ++char expansionboard_name[16]; ++ ++#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE) ++ ++#include ++#include ++ ++#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_zippy_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_zippy_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_ENC28J60_IRQ); ++ set_irq_type(omap3beagle_zippy_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_zippy_spi_board_info, ++ ARRAY_SIZE(omap3beagle_zippy_spi_board_info)); ++} ++ ++#else ++static inline void __init omap3beagle_enc28j60_init(void) { return; } ++#endif ++ ++#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE) ++ ++#include ++#include ++ ++#define OMAP3BEAGLE_GPIO_KS8851_IRQ 157 ++ ++static struct omap2_mcspi_device_config ks8851_spi_chip_info = { ++ .turbo_mode = 0, ++ .single_channel = 1, /* 0: slave, 1: master */ ++}; ++ ++static struct spi_board_info omap3beagle_zippy2_spi_board_info[] __initdata = { ++ { ++ .modalias = "ks8851", ++ .bus_num = 4, ++ .chip_select = 0, ++ .max_speed_hz = 36000000, ++ .controller_data = &ks8851_spi_chip_info, ++ }, ++}; ++ ++static void __init omap3beagle_ks8851_init(void) ++{ ++ if ((gpio_request(OMAP3BEAGLE_GPIO_KS8851_IRQ, "KS8851_IRQ") == 0) && ++ (gpio_direction_input(OMAP3BEAGLE_GPIO_KS8851_IRQ) == 0)) { ++ gpio_export(OMAP3BEAGLE_GPIO_KS8851_IRQ, 0); ++ omap3beagle_zippy2_spi_board_info[0].irq = OMAP_GPIO_IRQ(OMAP3BEAGLE_GPIO_KS8851_IRQ); ++ set_irq_type(omap3beagle_zippy2_spi_board_info[0].irq, IRQ_TYPE_EDGE_FALLING); ++ } else { ++ printk(KERN_ERR "could not obtain gpio for KS8851_IRQ\n"); ++ return; ++ } ++ ++ spi_register_board_info(omap3beagle_zippy2_spi_board_info, ++ ARRAY_SIZE(omap3beagle_zippy2_spi_board_info)); ++} ++ ++#else ++static inline void __init omap3beagle_ks8851_init(void) { return; } ++#endif ++ + static struct mtd_partition omap3beagle_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { +@@ -262,6 +349,12 @@ static struct omap2_hsmmc_info mmc[] = { + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = 29, + }, ++ { ++ .mmc = 2, ++ .caps = MMC_CAP_4_BIT_DATA, ++ .transceiver = true, ++ .ocr_mask = 0x00100000, /* 3.3V */ ++ }, + {} /* Terminator */ + }; + +@@ -457,7 +550,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, +@@ -472,10 +565,24 @@ static struct i2c_board_info __initdata beagle_i2c_eeprom[] = { + }, + }; + ++#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, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom)); +@@ -609,6 +716,15 @@ static struct omap_musb_board_data musb_board_data = { + .power = 100, + }; + ++static int __init expansionboard_setup(char *str) ++{ ++ if (!str) ++ return -EINVAL; ++ strncpy(expansionboard_name, str, 16); ++ printk(KERN_INFO "Beagle expansionboard: %s\n", expansionboard_name); ++ return 0; ++} ++ + static void __init omap3_beagle_init(void) + { + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); +@@ -623,6 +739,24 @@ static void __init omap3_beagle_init(void) + /* REVISIT leave DVI powered down until it's needed ... */ + gpio_direction_output(170, true); + ++ if(!strcmp(expansionboard_name, "zippy")) ++ { ++ printk(KERN_INFO "Beagle expansionboard: initializing enc28j60\n"); ++ omap3beagle_enc28j60_init(); ++ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n"); ++ mmc[1].gpio_wp = 141; ++ mmc[1].gpio_cd = 162; ++ } ++ ++ if(!strcmp(expansionboard_name, "zippy2")) ++ { ++ printk(KERN_INFO "Beagle expansionboard: initializing ks_8851\n"); ++ omap3beagle_ks8851_init(); ++ printk(KERN_INFO "Beagle expansionboard: assigning GPIO 141 and 162 to MMC1\n"); ++ mmc[1].gpio_wp = 141; ++ mmc[1].gpio_cd = 162; ++ } ++ + usb_musb_init(&musb_board_data); + usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); +@@ -634,6 +768,8 @@ static void __init omap3_beagle_init(void) + beagle_display_init(); + } + ++early_param("buddy", expansionboard_setup); ++ + MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") + /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ + .boot_params = 0x80000100, +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0006-ARM-OMAP-beagleboard-pre-export-GPIOs-to-userspace-w.patch b/extras/recipes-kernel/linux/linux-omap/base/0006-ARM-OMAP-beagleboard-pre-export-GPIOs-to-userspace-w.patch new file mode 100644 index 00000000..3c8547a1 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0006-ARM-OMAP-beagleboard-pre-export-GPIOs-to-userspace-w.patch @@ -0,0 +1,57 @@ +From 0c2c9a4d7fd299444b66e08aa34acc868261003f Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Sun, 5 Dec 2010 13:25:00 +0100 +Subject: [PATCH 06/28] ARM: OMAP: beagleboard: pre-export GPIOs to userspace when using a Tincantools trainerboard + +This really needs a for loop, patches welcome + +Signed-off-by: Koen Kooi +--- + arch/arm/mach-omap2/board-omap3beagle.c | 31 +++++++++++++++++++++++++++++++ + 1 files changed, 31 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index d777b3b..64a181e 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -757,6 +757,37 @@ static void __init omap3_beagle_init(void) + mmc[1].gpio_cd = 162; + } + ++ if(!strcmp(expansionboard_name, "trainer")) ++ { ++ printk(KERN_INFO "Beagle expansionboard: exporting GPIOs 130-141,162 to userspace\n"); ++ gpio_request(130, "sysfs"); ++ gpio_export(130, 1); ++ gpio_request(131, "sysfs"); ++ gpio_export(131, 1); ++ gpio_request(132, "sysfs"); ++ gpio_export(132, 1); ++ gpio_request(133, "sysfs"); ++ gpio_export(133, 1); ++ gpio_request(134, "sysfs"); ++ gpio_export(134, 1); ++ gpio_request(135, "sysfs"); ++ gpio_export(135, 1); ++ gpio_request(136, "sysfs"); ++ gpio_export(136, 1); ++ gpio_request(137, "sysfs"); ++ gpio_export(137, 1); ++ gpio_request(138, "sysfs"); ++ gpio_export(138, 1); ++ gpio_request(139, "sysfs"); ++ gpio_export(139, 1); ++ gpio_request(140, "sysfs"); ++ gpio_export(140, 1); ++ gpio_request(141, "sysfs"); ++ gpio_export(141, 1); ++ gpio_request(162, "sysfs"); ++ gpio_export(162, 1); ++ } ++ + usb_musb_init(&musb_board_data); + usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0007-modedb.c-add-proper-720p60-mode.patch b/extras/recipes-kernel/linux/linux-omap/base/0007-modedb.c-add-proper-720p60-mode.patch new file mode 100644 index 00000000..575ee6f5 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0007-modedb.c-add-proper-720p60-mode.patch @@ -0,0 +1,28 @@ +From ed12d865de851c5aed3ae7685337551b831bb045 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Mon, 8 Mar 2010 14:38:31 +0100 +Subject: [PATCH 07/28] modedb.c: add proper 720p60 mode + +Signed-off-by: Koen Kooi +--- + 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 de450c1..1cd8153 100644 +--- a/drivers/video/modedb.c ++++ b/drivers/video/modedb.c +@@ -46,6 +46,10 @@ static const struct fb_videomode modedb[] = { + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, + 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 ++ }, { + /* 800x600 @ 56 Hz, 35.15 kHz hsync */ + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, + 0, FB_VMODE_NONINTERLACED +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0008-mmc-don-t-display-single-block-read-console-messages.patch b/extras/recipes-kernel/linux/linux-omap/base/0008-mmc-don-t-display-single-block-read-console-messages.patch new file mode 100644 index 00000000..7e776412 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0008-mmc-don-t-display-single-block-read-console-messages.patch @@ -0,0 +1,28 @@ +From 13235700be3729d183143bdb75ee58742372d6aa Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Mon, 4 Jan 2010 19:20:25 -0800 +Subject: [PATCH 08/28] mmc: don't display single block read console messages + +mmc: don't display single block read console messages +--- + drivers/mmc/card/block.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c +index 217f820..b0b68cc 100644 +--- a/drivers/mmc/card/block.c ++++ b/drivers/mmc/card/block.c +@@ -434,8 +434,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req) + if (brq.cmd.error || brq.data.error || brq.stop.error) { + if (brq.data.blocks > 1 && rq_data_dir(req) == READ) { + /* Redo read one sector at a time */ +- printk(KERN_WARNING "%s: retrying using single " +- "block read\n", req->rq_disk->disk_name); ++ /* printk(KERN_WARNING "%s: retrying using single " ++ "block read\n", req->rq_disk->disk_name); */ + disable_multi = 1; + continue; + } +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0009-MTD-silence-ecc-errors-on-mtdblock0.patch b/extras/recipes-kernel/linux/linux-omap/base/0009-MTD-silence-ecc-errors-on-mtdblock0.patch new file mode 100644 index 00000000..e665e23a --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0009-MTD-silence-ecc-errors-on-mtdblock0.patch @@ -0,0 +1,63 @@ +From 8b0c56b910811acd23c15bed273b3dbd959ef96a Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Mon, 26 Apr 2010 11:17:26 -0700 +Subject: [PATCH 09/28] MTD: silence ecc errors on mtdblock0 + +mtdblock0 is the x-load partition, which uses hw ecc +this confuses linux, which uses sw ecc +this patch silences ecc error messages when linux peeks into mtdblock0 +* not for upstream submission * +--- + block/blk-core.c | 7 ++++--- + drivers/mtd/nand/nand_ecc.c | 2 +- + fs/buffer.c | 3 ++- + 3 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/block/blk-core.c b/block/blk-core.c +index 4ce953f..1ef9a01 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2028,9 +2028,10 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) + + if (error && req->cmd_type == REQ_TYPE_FS && + !(req->cmd_flags & REQ_QUIET)) { +- printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n", +- req->rq_disk ? req->rq_disk->disk_name : "?", +- (unsigned long long)blk_rq_pos(req)); ++ if (req->rq_disk && (strcmp(req->rq_disk->disk_name, "mtdblock0") != 0)) ++ printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n", ++ req->rq_disk ? req->rq_disk->disk_name : "?", ++ (unsigned long long)blk_rq_pos(req)); + } + + blk_account_io_completion(req, nr_bytes); +diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c +index 271b8e7..5924ba7 100644 +--- a/drivers/mtd/nand/nand_ecc.c ++++ b/drivers/mtd/nand/nand_ecc.c +@@ -507,7 +507,7 @@ int __nand_correct_data(unsigned char *buf, + if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1) + return 1; /* error in ecc data; no action needed */ + +- printk(KERN_ERR "uncorrectable error : "); ++// printk(KERN_ERR "uncorrectable error : "); + return -1; + } + EXPORT_SYMBOL(__nand_correct_data); +diff --git a/fs/buffer.c b/fs/buffer.c +index 5930e38..06a00d5 100644 +--- a/fs/buffer.c ++++ b/fs/buffer.c +@@ -114,7 +114,8 @@ static int quiet_error(struct buffer_head *bh) + static void buffer_io_error(struct buffer_head *bh) + { + char b[BDEVNAME_SIZE]; +- printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n", ++ if (strcmp(bdevname(bh->b_bdev, b), "mtdblock0") != 0) ++ printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n", + bdevname(bh->b_bdev, b), + (unsigned long long)bh->b_blocknr); + } +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0010-Miracle-patch.patch b/extras/recipes-kernel/linux/linux-omap/base/0010-Miracle-patch.patch new file mode 100644 index 00000000..c5eba83d --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0010-Miracle-patch.patch @@ -0,0 +1,504 @@ +From ce4f1f734efd638af01f1849ffffdc2746ad4a55 Mon Sep 17 00:00:00 2001 +From: Mike Galbraith +Date: Fri, 19 Nov 2010 12:52:42 +0100 +Subject: [PATCH 10/28] Miracle patch +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +On Sun, 2010-11-14 at 16:26 -0800, Linus Torvalds wrote: +> On Sun, Nov 14, 2010 at 4:15 PM, Linus Torvalds +> wrote: +> > +> > THAT is why I think it's so silly to try to be so strict and walk over +> > all processes while holding a couple of spinlocks. +> +> Btw, let me say that I think the patch is great even with that thing +> in. It looks clean, the thing I'm complaining about is not a big deal, +> and it seems to perform very much as advertized. The difference with +> autogroup scheduling is very noticeable with a simple "make -j64" +> kernel compile. +> +> So I really don't think it's a big deal. The sysctl handler isn't even +> complicated. But boy does it hurt my eyes to see a spinlock held +> around a "do_each_thread()". And I do get the feeling that the +> simplest way to fix it would be to just remove the code entirely, and +> just say that "enabling/disabling may be delayed for old processes +> with existing autogroups". + +Which is what I just did. If the oddball case isn't a big deal, the +patch shrinks, which is a good thing. I just wanted to cover all bases. + +Patchlet with handler whacked: + +A recurring complaint from CFS users is that parallel kbuild has a negative +impact on desktop interactivity. This patch implements an idea from Linus, +to automatically create task groups. This patch only implements Linus' per +tty task group suggestion, and only for fair class tasks, but leaves the way +open for enhancement. + +Implementation: each task's signal struct contains an inherited pointer to a +refcounted autogroup struct containing a task group pointer, the default for +all tasks pointing to the init_task_group. When a task calls __proc_set_tty(), +the process wide reference to the default group is dropped, a new task group is +created, and the process is moved into the new task group. Children thereafter +inherit this task group, and increase it's refcount. On exit, a reference to the +current task group is dropped when the last reference to each signal struct is +dropped. The task group is destroyed when the last signal struct referencing +it is freed. At runqueue selection time, IFF a task has no cgroup assignment, +it's current autogroup is used. + +The feature is enabled from boot by default if CONFIG_SCHED_AUTOGROUP is +selected, but can be disabled via the boot option noautogroup, and can be +also be turned on/off on the fly via.. + echo [01] > /proc/sys/kernel/sched_autogroup_enabled. +..which will automatically move tasks to/from the root task group. + +Some numbers. + +A 100% hog overhead measurement proggy pinned to the same CPU as a make -j10 + +About measurement proggy: + pert/sec = perturbations/sec + min/max/avg = scheduler service latencies in usecs + sum/s = time accrued by the competition per sample period (1 sec here) + overhead = %CPU received by the competition per sample period + +pert/s: 31 >40475.37us: 3 min: 0.37 max:48103.60 avg:29573.74 sum/s:916786us overhead:90.24% +pert/s: 23 >41237.70us: 12 min: 0.36 max:56010.39 avg:40187.01 sum/s:924301us overhead:91.99% +pert/s: 24 >42150.22us: 12 min: 8.86 max:61265.91 avg:39459.91 sum/s:947038us overhead:92.20% +pert/s: 26 >42344.91us: 11 min: 3.83 max:52029.60 avg:36164.70 sum/s:940282us overhead:91.12% +pert/s: 24 >44262.90us: 14 min: 5.05 max:82735.15 avg:40314.33 sum/s:967544us overhead:92.22% + +Same load with this patch applied. + +pert/s: 229 >5484.43us: 41 min: 0.15 max:12069.42 avg:2193.81 sum/s:502382us overhead:50.24% +pert/s: 222 >5652.28us: 43 min: 0.46 max:12077.31 avg:2248.56 sum/s:499181us overhead:49.92% +pert/s: 211 >5809.38us: 43 min: 0.16 max:12064.78 avg:2381.70 sum/s:502538us overhead:50.25% +pert/s: 223 >6147.92us: 43 min: 0.15 max:16107.46 avg:2282.17 sum/s:508925us overhead:50.49% +pert/s: 218 >6252.64us: 43 min: 0.16 max:12066.13 avg:2324.11 sum/s:506656us overhead:50.27% + +Average service latency is an order of magnitude better with autogroup. +(Imagine that pert were Xorg or whatnot instead) + +Using Mathieu Desnoyers' wakeup-latency testcase: + +With taskset -c 3 make -j 10 running.. + +taskset -c 3 ./wakeup-latency& sleep 30;killall wakeup-latency + +without: +maximum latency: 42963.2 µs +average latency: 9077.0 µs +missed timer events: 0 + +with: +maximum latency: 4160.7 µs +average latency: 149.4 µs +missed timer events: 0 + +Signed-off-by: Mike Galbraith +--- + Documentation/kernel-parameters.txt | 2 + + drivers/tty/tty_io.c | 1 + + include/linux/sched.h | 19 +++++ + init/Kconfig | 12 +++ + kernel/fork.c | 5 +- + kernel/sched.c | 25 ++++-- + kernel/sched_autogroup.c | 140 +++++++++++++++++++++++++++++++++++ + kernel/sched_autogroup.h | 18 +++++ + kernel/sysctl.c | 11 +++ + 9 files changed, 224 insertions(+), 9 deletions(-) + create mode 100644 kernel/sched_autogroup.c + create mode 100644 kernel/sched_autogroup.h + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 01ece1b..1031923 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -1622,6 +1622,8 @@ and is between 256 and 4096 characters. It is defined in the file + noapic [SMP,APIC] Tells the kernel to not make use of any + IOAPICs that may be present in the system. + ++ noautogroup Disable scheduler automatic task group creation. ++ + nobats [PPC] Do not use BATs for mapping kernel lowmem + on "Classic" PPC cores. + +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index 35480dd..1849f4a 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -3169,6 +3169,7 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) + put_pid(tsk->signal->tty_old_pgrp); + tsk->signal->tty = tty_kref_get(tty); + tsk->signal->tty_old_pgrp = NULL; ++ sched_autogroup_create_attach(tsk); + } + + static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) +diff --git a/include/linux/sched.h b/include/linux/sched.h +index 2238745..3a775e3 100644 +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -509,6 +509,8 @@ struct thread_group_cputimer { + spinlock_t lock; + }; + ++struct autogroup; ++ + /* + * NOTE! "signal_struct" does not have it's own + * locking, because a shared signal_struct always +@@ -576,6 +578,9 @@ struct signal_struct { + + struct tty_struct *tty; /* NULL if no tty */ + ++#ifdef CONFIG_SCHED_AUTOGROUP ++ struct autogroup *autogroup; ++#endif + /* + * Cumulative resource counters for dead threads in the group, + * and for reaped dead child processes forked by this group. +@@ -1931,6 +1936,20 @@ int sched_rt_handler(struct ctl_table *table, int write, + + extern unsigned int sysctl_sched_compat_yield; + ++#ifdef CONFIG_SCHED_AUTOGROUP ++extern unsigned int sysctl_sched_autogroup_enabled; ++ ++extern void sched_autogroup_create_attach(struct task_struct *p); ++extern void sched_autogroup_detach(struct task_struct *p); ++extern void sched_autogroup_fork(struct signal_struct *sig); ++extern void sched_autogroup_exit(struct signal_struct *sig); ++#else ++static inline void sched_autogroup_create_attach(struct task_struct *p) { } ++static inline void sched_autogroup_detach(struct task_struct *p) { } ++static inline void sched_autogroup_fork(struct signal_struct *sig) { } ++static inline void sched_autogroup_exit(struct signal_struct *sig) { } ++#endif ++ + #ifdef CONFIG_RT_MUTEXES + extern int rt_mutex_getprio(struct task_struct *p); + extern void rt_mutex_setprio(struct task_struct *p, int prio); +diff --git a/init/Kconfig b/init/Kconfig +index c972899..a4985d9 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -741,6 +741,18 @@ config NET_NS + + endif # NAMESPACES + ++config SCHED_AUTOGROUP ++ bool "Automatic process group scheduling" ++ select CGROUPS ++ select CGROUP_SCHED ++ select FAIR_GROUP_SCHED ++ help ++ This option optimizes the scheduler for common desktop workloads by ++ automatically creating and populating task groups. This separation ++ of workloads isolates aggressive CPU burners (like build jobs) from ++ desktop applications. Task group autogeneration is currently based ++ upon task tty association. ++ + config MM_OWNER + bool + +diff --git a/kernel/fork.c b/kernel/fork.c +index 5447dc7..70ea75f 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -174,8 +174,10 @@ static inline void free_signal_struct(struct signal_struct *sig) + + static inline void put_signal_struct(struct signal_struct *sig) + { +- if (atomic_dec_and_test(&sig->sigcnt)) ++ if (atomic_dec_and_test(&sig->sigcnt)) { ++ sched_autogroup_exit(sig); + free_signal_struct(sig); ++ } + } + + void __put_task_struct(struct task_struct *tsk) +@@ -905,6 +907,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) + posix_cpu_timers_init_group(sig); + + tty_audit_fork(sig); ++ sched_autogroup_fork(sig); + + sig->oom_adj = current->signal->oom_adj; + sig->oom_score_adj = current->signal->oom_score_adj; +diff --git a/kernel/sched.c b/kernel/sched.c +index 297d1a0..53ff9a1 100644 +--- a/kernel/sched.c ++++ b/kernel/sched.c +@@ -78,6 +78,7 @@ + + #include "sched_cpupri.h" + #include "workqueue_sched.h" ++#include "sched_autogroup.h" + + #define CREATE_TRACE_POINTS + #include +@@ -605,11 +606,14 @@ static inline int cpu_of(struct rq *rq) + */ + static inline struct task_group *task_group(struct task_struct *p) + { ++ struct task_group *tg; + struct cgroup_subsys_state *css; + + css = task_subsys_state_check(p, cpu_cgroup_subsys_id, + lockdep_is_held(&task_rq(p)->lock)); +- return container_of(css, struct task_group, css); ++ tg = container_of(css, struct task_group, css); ++ ++ return autogroup_task_group(p, tg); + } + + /* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ +@@ -2063,6 +2067,7 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) + #include "sched_idletask.c" + #include "sched_fair.c" + #include "sched_rt.c" ++#include "sched_autogroup.c" + #include "sched_stoptask.c" + #ifdef CONFIG_SCHED_DEBUG + # include "sched_debug.c" +@@ -8164,7 +8169,7 @@ void __init sched_init(void) + #ifdef CONFIG_CGROUP_SCHED + list_add(&init_task_group.list, &task_groups); + INIT_LIST_HEAD(&init_task_group.children); +- ++ autogroup_init(&init_task); + #endif /* CONFIG_CGROUP_SCHED */ + + #if defined CONFIG_FAIR_GROUP_SCHED && defined CONFIG_SMP +@@ -8694,15 +8699,11 @@ void sched_destroy_group(struct task_group *tg) + /* change task's runqueue when it moves between groups. + * The caller of this function should have put the task in its new group + * by now. This function just updates tsk->se.cfs_rq and tsk->se.parent to +- * reflect its new group. ++ * reflect its new group. Called with the runqueue lock held. + */ +-void sched_move_task(struct task_struct *tsk) ++void __sched_move_task(struct task_struct *tsk, struct rq *rq) + { + int on_rq, running; +- unsigned long flags; +- struct rq *rq; +- +- rq = task_rq_lock(tsk, &flags); + + running = task_current(rq, tsk); + on_rq = tsk->se.on_rq; +@@ -8723,7 +8724,15 @@ void sched_move_task(struct task_struct *tsk) + tsk->sched_class->set_curr_task(rq); + if (on_rq) + enqueue_task(rq, tsk, 0); ++} + ++void sched_move_task(struct task_struct *tsk) ++{ ++ struct rq *rq; ++ unsigned long flags; ++ ++ rq = task_rq_lock(tsk, &flags); ++ __sched_move_task(tsk, rq); + task_rq_unlock(rq, &flags); + } + #endif /* CONFIG_CGROUP_SCHED */ +diff --git a/kernel/sched_autogroup.c b/kernel/sched_autogroup.c +new file mode 100644 +index 0000000..62f1d0e +--- /dev/null ++++ b/kernel/sched_autogroup.c +@@ -0,0 +1,140 @@ ++#ifdef CONFIG_SCHED_AUTOGROUP ++ ++unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1; ++ ++struct autogroup { ++ struct kref kref; ++ struct task_group *tg; ++}; ++ ++static struct autogroup autogroup_default; ++ ++static void autogroup_init(struct task_struct *init_task) ++{ ++ autogroup_default.tg = &init_task_group; ++ kref_init(&autogroup_default.kref); ++ init_task->signal->autogroup = &autogroup_default; ++} ++ ++static inline void autogroup_destroy(struct kref *kref) ++{ ++ struct autogroup *ag = container_of(kref, struct autogroup, kref); ++ struct task_group *tg = ag->tg; ++ ++ kfree(ag); ++ sched_destroy_group(tg); ++} ++ ++static inline void autogroup_kref_put(struct autogroup *ag) ++{ ++ kref_put(&ag->kref, autogroup_destroy); ++} ++ ++static inline struct autogroup *autogroup_kref_get(struct autogroup *ag) ++{ ++ kref_get(&ag->kref); ++ return ag; ++} ++ ++static inline struct autogroup *autogroup_create(void) ++{ ++ struct autogroup *ag = kmalloc(sizeof(*ag), GFP_KERNEL); ++ ++ if (!ag) ++ goto out_fail; ++ ++ ag->tg = sched_create_group(&init_task_group); ++ kref_init(&ag->kref); ++ ++ if (!(IS_ERR(ag->tg))) ++ return ag; ++ ++out_fail: ++ if (ag) { ++ kfree(ag); ++ WARN_ON(1); ++ } else ++ WARN_ON(1); ++ ++ return autogroup_kref_get(&autogroup_default); ++} ++ ++static inline struct task_group * ++autogroup_task_group(struct task_struct *p, struct task_group *tg) ++{ ++ int enabled = ACCESS_ONCE(sysctl_sched_autogroup_enabled); ++ ++ enabled &= (tg == &root_task_group); ++ enabled &= (p->sched_class == &fair_sched_class); ++ enabled &= (!(p->flags & PF_EXITING)); ++ ++ if (enabled) ++ return p->signal->autogroup->tg; ++ ++ return tg; ++} ++ ++static void ++autogroup_move_group(struct task_struct *p, struct autogroup *ag) ++{ ++ struct autogroup *prev; ++ struct task_struct *t; ++ struct rq *rq; ++ unsigned long flags; ++ ++ rq = task_rq_lock(p, &flags); ++ prev = p->signal->autogroup; ++ if (prev == ag) { ++ task_rq_unlock(rq, &flags); ++ return; ++ } ++ ++ p->signal->autogroup = autogroup_kref_get(ag); ++ __sched_move_task(p, rq); ++ task_rq_unlock(rq, &flags); ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(t, &p->thread_group, thread_group) { ++ sched_move_task(t); ++ } ++ rcu_read_unlock(); ++ ++ autogroup_kref_put(prev); ++} ++ ++void sched_autogroup_create_attach(struct task_struct *p) ++{ ++ struct autogroup *ag = autogroup_create(); ++ ++ autogroup_move_group(p, ag); ++ /* drop extra refrence added by autogroup_create() */ ++ autogroup_kref_put(ag); ++} ++EXPORT_SYMBOL(sched_autogroup_create_attach); ++ ++/* currently has no users */ ++void sched_autogroup_detach(struct task_struct *p) ++{ ++ autogroup_move_group(p, &autogroup_default); ++} ++EXPORT_SYMBOL(sched_autogroup_detach); ++ ++void sched_autogroup_fork(struct signal_struct *sig) ++{ ++ sig->autogroup = autogroup_kref_get(current->signal->autogroup); ++} ++ ++void sched_autogroup_exit(struct signal_struct *sig) ++{ ++ autogroup_kref_put(sig->autogroup); ++} ++ ++static int __init setup_autogroup(char *str) ++{ ++ sysctl_sched_autogroup_enabled = 0; ++ ++ return 1; ++} ++ ++__setup("noautogroup", setup_autogroup); ++#endif +diff --git a/kernel/sched_autogroup.h b/kernel/sched_autogroup.h +new file mode 100644 +index 0000000..6048f5d +--- /dev/null ++++ b/kernel/sched_autogroup.h +@@ -0,0 +1,18 @@ ++#ifdef CONFIG_SCHED_AUTOGROUP ++ ++static void __sched_move_task(struct task_struct *tsk, struct rq *rq); ++ ++static inline struct task_group * ++autogroup_task_group(struct task_struct *p, struct task_group *tg); ++ ++#else /* !CONFIG_SCHED_AUTOGROUP */ ++ ++static inline void autogroup_init(struct task_struct *init_task) { } ++ ++static inline struct task_group * ++autogroup_task_group(struct task_struct *p, struct task_group *tg) ++{ ++ return tg; ++} ++ ++#endif /* CONFIG_SCHED_AUTOGROUP */ +diff --git a/kernel/sysctl.c b/kernel/sysctl.c +index 5abfa15..b162f65 100644 +--- a/kernel/sysctl.c ++++ b/kernel/sysctl.c +@@ -382,6 +382,17 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec, + }, ++#ifdef CONFIG_SCHED_AUTOGROUP ++ { ++ .procname = "sched_autogroup_enabled", ++ .data = &sysctl_sched_autogroup_enabled, ++ .maxlen = sizeof(unsigned int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, ++ .extra1 = &zero, ++ .extra2 = &one, ++ }, ++#endif + #ifdef CONFIG_PROVE_LOCKING + { + .procname = "prove_locking", +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0011-ARM-OMAP-add-omap_rev_-macros.patch b/extras/recipes-kernel/linux/linux-omap/base/0011-ARM-OMAP-add-omap_rev_-macros.patch new file mode 100644 index 00000000..b89302bc --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0011-ARM-OMAP-add-omap_rev_-macros.patch @@ -0,0 +1,81 @@ +From 8b34449d7eb89e1ae1c1c84f90ef5ea1e397787e Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Tue, 23 Nov 2010 11:40:20 +0100 +Subject: [PATCH 11/28] ARM: OMAP: add omap_rev_* macros + +This is just to make the SGX modules build that depend on omap_rev_lt_3_0 + +Signed-off-by: Koen Kooi +--- + arch/arm/plat-omap/include/plat/cpu.h | 55 +++++++++++++++++++++++++++++++++ + 1 files changed, 55 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h +index 3fd8b40..1a8c347 100644 +--- a/arch/arm/plat-omap/include/plat/cpu.h ++++ b/arch/arm/plat-omap/include/plat/cpu.h +@@ -394,6 +394,61 @@ IS_OMAP_TYPE(3517, 0x3517) + #define OMAP4430_REV_ES2_0 0x44301044 + + /* ++ * Silicon revisions ++ */ ++#define OMAP_ES_1_0 0x00 ++#define OMAP_ES_2_0 0x10 ++#define OMAP_ES_2_1 0x20 ++#define OMAP_ES_3_0 0x30 ++#define OMAP_ES_3_1 0x40 ++ ++#define OMAP_REV_MASK 0x0000ff00 ++#define OMAP_REV_BITS ((omap_rev() & OMAP_REV_MASK) >> 8) ++ ++#define OMAP_REV_IS(revid) \ ++static inline u8 omap_rev_is_ ##revid (void) \ ++{ \ ++ return (OMAP_REV_BITS == OMAP_ES_ ##revid) ? 1 : 0; \ ++} ++ ++#define OMAP_REV_LT(revid) \ ++static inline u8 omap_rev_lt_ ##revid (void) \ ++{ \ ++ return (OMAP_REV_BITS < OMAP_ES_ ##revid) ? 1 : 0; \ ++} ++ ++#define OMAP_REV_LE(revid) \ ++static inline u8 omap_rev_le_ ##revid (void) \ ++{ \ ++ return (OMAP_REV_BITS <= OMAP_ES_ ##revid) ? 1 : 0; \ ++} ++ ++#define OMAP_REV_GT(revid) \ ++static inline u8 omap_rev_gt_ ##revid (void) \ ++{ \ ++ return (OMAP_REV_BITS > OMAP_ES_ ##revid) ? 1 : 0; \ ++} ++ ++#define OMAP_REV_GE(revid) \ ++static inline u8 omap_rev_ge_ ##revid (void) \ ++{ \ ++ return (OMAP_REV_BITS >= OMAP_ES_ ##revid) ? 1 : 0; \ ++} ++ ++#define OMAP_REV_FUNCTIONS(revid) \ ++ OMAP_REV_IS(revid) \ ++ OMAP_REV_LT(revid) \ ++ OMAP_REV_LE(revid) \ ++ OMAP_REV_GT(revid) \ ++ OMAP_REV_GE(revid) ++ ++OMAP_REV_FUNCTIONS(1_0) ++OMAP_REV_FUNCTIONS(2_0) ++OMAP_REV_FUNCTIONS(2_1) ++OMAP_REV_FUNCTIONS(3_0) ++OMAP_REV_FUNCTIONS(3_1) ++ ++/* + * omap_chip bits + * + * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0012-OMAP-DSS2-enable-hsclk-in-dsi_pll_init-for-OMAP36XX.patch b/extras/recipes-kernel/linux/linux-omap/base/0012-OMAP-DSS2-enable-hsclk-in-dsi_pll_init-for-OMAP36XX.patch new file mode 100644 index 00000000..7413b5f8 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0012-OMAP-DSS2-enable-hsclk-in-dsi_pll_init-for-OMAP36XX.patch @@ -0,0 +1,31 @@ +From cd8a01e55dc674bba0030b99bff4f58d587aaecd Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Mon, 10 May 2010 20:44:09 -0700 +Subject: [PATCH 12/28] OMAP: DSS2: enable hsclk in dsi_pll_init for OMAP36XX + +Signed-off-by: Koen Kooi +--- + drivers/video/omap2/dss/dpi.c | 7 ++++++- + 1 files changed, 6 insertions(+), 1 deletions(-) + +diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c +index 960e977..23047b6 100644 +--- a/drivers/video/omap2/dss/dpi.c ++++ b/drivers/video/omap2/dss/dpi.c +@@ -177,7 +177,12 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) + + #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL + dss_clk_enable(DSS_CLK_FCK2); +- r = dsi_pll_init(dssdev, 0, 1); ++ ++ if (cpu_is_omap3630()) ++ r = dsi_pll_init(dssdev, 1, 1); ++ else ++ r = dsi_pll_init(dssdev, 0, 1); ++ + if (r) + goto err3; + #endif +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0013-omap3-beagleboard-add-WIP-support-for-beagleboardtoy.patch b/extras/recipes-kernel/linux/linux-omap/base/0013-omap3-beagleboard-add-WIP-support-for-beagleboardtoy.patch new file mode 100644 index 00000000..af12b2c9 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0013-omap3-beagleboard-add-WIP-support-for-beagleboardtoy.patch @@ -0,0 +1,128 @@ +From f7d71be36165002251727019b1a03a19938bfa64 Mon Sep 17 00:00:00 2001 +From: Koen Kooi +Date: Mon, 20 Dec 2010 11:57:56 +0100 +Subject: [PATCH 13/28] omap3: beagleboard: add WIP support for beagleboardtoys WL12xx board + +Based on a patch by Luciano Coelho + +Signed-off-by: Koen Kooi +--- + arch/arm/mach-omap2/board-omap3beagle.c | 84 ++++++++++++++++++++++++++++++- + 1 files changed, 83 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 64a181e..59b26da 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -146,6 +146,67 @@ fail0: + + char expansionboard_name[16]; + ++#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE) ++#include ++#include ++ ++#define OMAP_BEAGLE_WLAN_EN_GPIO (139) ++#define OMAP_BEAGLE_WLAN_IRQ_GPIO (137) ++ ++struct wl12xx_platform_data omap_beagle_wlan_data __initdata = { ++ .irq = OMAP_GPIO_IRQ(OMAP_BEAGLE_WLAN_IRQ_GPIO), ++ .board_ref_clock = 2, /* 38.4 MHz */ ++}; ++ ++ static struct omap2_hsmmc_info mmcbbt[] = { ++ { ++ .mmc = 1, ++ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, ++ .gpio_wp = 29, ++ }, ++ { ++ .name = "wl1271", ++ .mmc = 2, ++ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, ++ .gpio_wp = -EINVAL, ++ .gpio_cd = -EINVAL, ++ .nonremovable = true, ++ }, ++ {} /* Terminator */ ++ }; ++ ++static struct regulator_consumer_supply beagle_vmmc2_supply = { ++ .supply = "vmmc", ++ .dev_name = "mmci-omap-hs.1", ++}; ++ ++static struct regulator_init_data beagle_vmmc2 = { ++ .constraints = { ++ .valid_ops_mask = REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = 1, ++ .consumer_supplies = &beagle_vmmc2_supply, ++}; ++ ++static struct fixed_voltage_config beagle_vwlan = { ++ .supply_name = "vwl1271", ++ .microvolts = 1800000, /* 1.8V */ ++ .gpio = OMAP_BEAGLE_WLAN_EN_GPIO, ++ .startup_delay = 70000, /* 70ms */ ++ .enable_high = 1, ++ .enabled_at_boot = 0, ++ .init_data = &beagle_vmmc2, ++}; ++ ++static struct platform_device omap_vwlan_device = { ++ .name = "reg-fixed-voltage", ++ .id = 1, ++ .dev = { ++ .platform_data = &beagle_vwlan, ++ }, ++}; ++#endif ++ + #if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE) + + #include +@@ -384,11 +445,24 @@ static int beagle_twl_gpio_setup(struct device *dev, + } + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; ++#if defined(CONFIG_WL1271) || defined(CONFIG_WL1271_MODULE) ++ if(!strcmp(expansionboard_name, "bbtoys-wifi")) { ++ omap2_hsmmc_init(mmcbbt); ++ /* link regulators to MMC adapters */ ++ beagle_vmmc1_supply.dev = mmcbbt[0].dev; ++ beagle_vsim_supply.dev = mmcbbt[0].dev; ++ } else { ++ omap2_hsmmc_init(mmc); ++ /* link regulators to MMC adapters */ ++ beagle_vmmc1_supply.dev = mmc[0].dev; ++ beagle_vsim_supply.dev = mmc[0].dev; ++ } ++#else + omap2_hsmmc_init(mmc); +- + /* link regulators to MMC adapters */ + beagle_vmmc1_supply.dev = mmc[0].dev; + beagle_vsim_supply.dev = mmc[0].dev; ++#endif + + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect +@@ -788,6 +862,14 @@ static void __init omap3_beagle_init(void) + gpio_export(162, 1); + } + ++ if(!strcmp(expansionboard_name, "bbtoys-wifi")) ++ { ++ if (wl12xx_set_platform_data(&omap_beagle_wlan_data)) ++ pr_err("error setting wl12xx data\n"); ++ printk(KERN_INFO "Beagle expansionboard: registering wl12xx platform device\n"); ++ platform_device_register(&omap_vwlan_device); ++ } ++ + usb_musb_init(&musb_board_data); + usb_ehci_init(&ehci_pdata); + omap3beagle_flash_init(); +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0014-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch b/extras/recipes-kernel/linux/linux-omap/base/0014-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch new file mode 100644 index 00000000..2eac323b --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0014-drivers-net-smsc911x-return-ENODEV-if-device-is-not-.patch @@ -0,0 +1,29 @@ +From a47bbc5c9742e4ce250ee3bfba62732f3fea40b7 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Tue, 15 Dec 2009 15:17:44 -0800 +Subject: [PATCH 14/28] drivers: net: smsc911x: return ENODEV if device is not found + +Signed-off-by: Steve Sakoman +--- + 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 64bfdae..ba2a00e 100644 +--- a/drivers/net/smsc911x.c ++++ b/drivers/net/smsc911x.c +@@ -2019,8 +2019,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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0015-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch b/extras/recipes-kernel/linux/linux-omap/base/0015-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch new file mode 100644 index 00000000..74691ab8 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0015-drivers-input-touchscreen-ads7846-return-ENODEV-if-d.patch @@ -0,0 +1,47 @@ +From 713eb96dd137e1436198aa07094049ae0e0f9f1f Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Tue, 15 Dec 2009 15:24:10 -0800 +Subject: [PATCH 15/28] drivers: input: touchscreen: ads7846: return ENODEV if device is not found + +Signed-off-by: Steve Sakoman +--- + 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 14ea54b..c775e38 100644 +--- a/drivers/input/touchscreen/ads7846.c ++++ b/drivers/input/touchscreen/ads7846.c +@@ -1325,11 +1325,18 @@ static int __devinit ads7846_probe(struct spi_device *spi) + * the touchscreen, in case it's not connected. + */ + if (ts->model == 7845) +- ads7845_read12_ser(&spi->dev, PWRDOWN); ++ err = ads7845_read12_ser(&spi->dev, PWRDOWN); + else +- (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; +@@ -1353,7 +1360,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) + err_put_regulator: + regulator_put(ts->reg); + 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) +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0016-ASoC-enable-audio-capture-by-default-for-twl4030.patch b/extras/recipes-kernel/linux/linux-omap/base/0016-ASoC-enable-audio-capture-by-default-for-twl4030.patch new file mode 100644 index 00000000..081aa5b9 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0016-ASoC-enable-audio-capture-by-default-for-twl4030.patch @@ -0,0 +1,27 @@ +From de63bf4fdf6c64e543c207792cb2d8ebcd089342 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 17 Dec 2009 12:45:20 -0800 +Subject: [PATCH 16/28] 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 cbebec6..430cd10 100644 +--- a/sound/soc/codecs/twl4030.c ++++ b/sound/soc/codecs/twl4030.c +@@ -56,8 +56,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { + 0x00, /* REG_OPTION (0x2) */ + 0x00, /* REG_UNKNOWN (0x3) */ + 0x00, /* REG_MICBIAS_CTL (0x4) */ +- 0x00, /* 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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0017-MFD-enable-madc-clock.patch b/extras/recipes-kernel/linux/linux-omap/base/0017-MFD-enable-madc-clock.patch new file mode 100644 index 00000000..2f3d1a43 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0017-MFD-enable-madc-clock.patch @@ -0,0 +1,51 @@ +From 18934b05f81025c1254d64c1774832e95187cbd9 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Sat, 23 Jan 2010 06:26:54 -0800 +Subject: [PATCH 17/28] MFD: enable madc clock + +--- + drivers/mfd/twl-core.c | 8 ++++++++ + include/linux/i2c/twl.h | 1 + + 2 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c +index 35275ba..5aa7358 100644 +--- a/drivers/mfd/twl-core.c ++++ b/drivers/mfd/twl-core.c +@@ -208,6 +208,11 @@ + + /* Few power values */ + #define R_CFG_BOOT 0x05 ++#define R_GPBR1 0x0C ++ ++/* MADC clock values for R_GPBR1 */ ++#define MADC_HFCLK_EN 0x80 ++#define DEFAULT_MADC_CLK_EN 0x10 + + /* some fields in R_CFG_BOOT */ + #define HFCLK_FREQ_19p2_MHZ (1 << 0) +@@ -929,6 +934,9 @@ static void clocks_init(struct device *dev, + + e |= unprotect_pm_master(); + /* effect->MADC+USB ck en */ ++ if (twl_has_madc()) ++ e |= twl_i2c_write_u8(TWL_MODULE_INTBR, ++ MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, R_GPBR1); + e |= twl_i2c_write_u8(TWL_MODULE_PM_MASTER, ctrl, R_CFG_BOOT); + e |= protect_pm_master(); + +diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h +index c760991..cfdfdd3 100644 +--- a/include/linux/i2c/twl.h ++++ b/include/linux/i2c/twl.h +@@ -74,6 +74,7 @@ + + #define TWL_MODULE_USB TWL4030_MODULE_USB + #define TWL_MODULE_AUDIO_VOICE TWL4030_MODULE_AUDIO_VOICE ++#define TWL_MODULE_INTBR TWL4030_MODULE_INTBR + #define TWL_MODULE_PIH TWL4030_MODULE_PIH + #define TWL_MODULE_MADC TWL4030_MODULE_MADC + #define TWL_MODULE_MAIN_CHARGE TWL4030_MODULE_MAIN_CHARGE +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0018-MFD-add-twl4030-madc-driver.patch b/extras/recipes-kernel/linux/linux-omap/base/0018-MFD-add-twl4030-madc-driver.patch new file mode 100644 index 00000000..a55136db --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0018-MFD-add-twl4030-madc-driver.patch @@ -0,0 +1,740 @@ +From 562dc52ebe3df1e5d23416e78306db7c568dc427 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 17 Dec 2009 14:19:34 -0800 +Subject: [PATCH 18/28] MFD: add twl4030 madc driver + +--- + drivers/mfd/Kconfig | 21 ++ + drivers/mfd/Makefile | 1 + + drivers/mfd/twl4030-madc.c | 537 ++++++++++++++++++++++++++++++++++++++ + include/linux/i2c/twl4030-madc.h | 130 +++++++++ + 4 files changed, 689 insertions(+), 0 deletions(-) + create mode 100644 drivers/mfd/twl4030-madc.c + create mode 100644 include/linux/i2c/twl4030-madc.h + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index 3a1493b..26ca160 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -186,6 +186,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 TWL6030_PWM + tristate "TWL6030 PWM (Pulse Width Modulator) Support" + depends on TWL4030_CORE +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index f54b365..8c4ccb2 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -39,6 +39,7 @@ obj-$(CONFIG_MENELAUS) += menelaus.o + obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-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_TWL6030_PWM) += twl6030-pwm.o + + obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o +diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c +new file mode 100644 +index 0000000..4adf880 +--- /dev/null ++++ b/drivers/mfd/twl4030-madc.c +@@ -0,0 +1,537 @@ ++/* ++ * TWL4030 MADC module driver ++ * ++ * Copyright (C) 2008 Nokia Corporation ++ * Mikko Ylinen ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 = twl_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 = twl_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<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<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 = twl_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 = twl_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 = twl_i2c_read_u8(TWL4030_MODULE_USB, ++ ®val, TWL4030_USB_CARKIT_ANA_CTRL); ++ ++ regval |= TWL4030_USB_SEL_MADC_MCPC; ++ ++ ret = twl_i2c_write_u8(TWL4030_MODULE_USB, ++ regval, TWL4030_USB_CARKIT_ANA_CTRL); ++ ++ ++ ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, ++ ®val, TWL4030_BCI_BCICTL1); ++ ++ regval |= TWL4030_BCI_MESBAT; ++ ++ ret = twl_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"); ++ +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 ++ * ++ * 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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch b/extras/recipes-kernel/linux/linux-omap/base/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch new file mode 100644 index 00000000..b24e4dd2 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0019-ARM-OMAP-Add-twl4030-madc-support-to-Overo.patch @@ -0,0 +1,32 @@ +From a33c4e0fb917ca059e900c2851849ba604758ff9 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 17 Dec 2009 14:27:15 -0800 +Subject: [PATCH 19/28] 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 cb26e5d..17f066a 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -369,10 +369,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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0020-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch b/extras/recipes-kernel/linux/linux-omap/base/0020-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch new file mode 100644 index 00000000..7028c17b --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0020-ARM-OMAP-Add-twl4030-madc-support-to-Beagle.patch @@ -0,0 +1,35 @@ +From fe51c97f26f8d6798909b1f22a5fb4ca84684f36 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 17 Dec 2009 14:32:36 -0800 +Subject: [PATCH 20/28] 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 f699701..9259780 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -604,6 +604,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, +@@ -612,6 +616,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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0021-OMAP-DSS2-Add-support-for-Samsung-LTE430WQ-F0C-panel.patch b/extras/recipes-kernel/linux/linux-omap/base/0021-OMAP-DSS2-Add-support-for-Samsung-LTE430WQ-F0C-panel.patch new file mode 100644 index 00000000..823ab9f3 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0021-OMAP-DSS2-Add-support-for-Samsung-LTE430WQ-F0C-panel.patch @@ -0,0 +1,173 @@ +From f8049ce6302904c1d08d8813f8a60b10b8a476e7 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Tue, 23 Feb 2010 14:40:27 -0800 +Subject: [PATCH 21/28] OMAP: DSS2: Add support for Samsung LTE430WQ-F0C panel + +--- + .../omap2/displays/panel-samsung-lte430wq-f0c.c | 154 ++++++++++++++++++++ + 1 files changed, 154 insertions(+), 0 deletions(-) + create mode 100644 drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c + +diff --git a/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c +new file mode 100644 +index 0000000..6a29f9c +--- /dev/null ++++ b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c +@@ -0,0 +1,154 @@ ++/* ++ * LCD panel driver for Samsung LTE430WQ-F0C ++ * ++ * Author: Steve Sakoman ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++ ++#include ++ ++static struct omap_video_timings samsung_lte_timings = { ++ .x_res = 480, ++ .y_res = 272, ++ ++ .pixel_clock = 9200, ++ ++ .hsw = 41, ++ .hfp = 8, ++ .hbp = 45-41, ++ ++ .vsw = 10, ++ .vfp = 4, ++ .vbp = 12-10, ++}; ++ ++static int samsung_lte_panel_power_on(struct omap_dss_device *dssdev) ++{ ++ int r; ++ ++ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) ++ return 0; ++ ++ r = omapdss_dpi_display_enable(dssdev); ++ if (r) ++ goto err0; ++ ++ if (dssdev->platform_enable) { ++ r = dssdev->platform_enable(dssdev); ++ if (r) ++ goto err1; ++ } ++ ++ return 0; ++err1: ++ omapdss_dpi_display_disable(dssdev); ++err0: ++ return r; ++} ++ ++static void samsung_lte_panel_power_off(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) ++ return; ++ ++ if (dssdev->platform_disable) ++ dssdev->platform_disable(dssdev); ++ ++ omapdss_dpi_display_disable(dssdev); ++} ++ ++static int samsung_lte_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 = samsung_lte_timings; ++ ++ return 0; ++} ++ ++static void samsung_lte_panel_remove(struct omap_dss_device *dssdev) ++{ ++} ++ ++static int samsung_lte_panel_enable(struct omap_dss_device *dssdev) ++{ ++ int r = 0; ++ ++ r = samsung_lte_panel_power_on(dssdev); ++ if (r) ++ return r; ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++} ++ ++static void samsung_lte_panel_disable(struct omap_dss_device *dssdev) ++{ ++ samsung_lte_panel_power_off(dssdev); ++ ++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; ++} ++ ++static int samsung_lte_panel_suspend(struct omap_dss_device *dssdev) ++{ ++ samsung_lte_panel_disable(dssdev); ++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; ++ return 0; ++} ++ ++static int samsung_lte_panel_resume(struct omap_dss_device *dssdev) ++{ ++ int r; ++ ++ r = samsung_lte_panel_enable(dssdev); ++ if (r) ++ return r; ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++} ++ ++static struct omap_dss_driver samsung_lte_driver = { ++ .probe = samsung_lte_panel_probe, ++ .remove = samsung_lte_panel_remove, ++ ++ .enable = samsung_lte_panel_enable, ++ .disable = samsung_lte_panel_disable, ++ .suspend = samsung_lte_panel_suspend, ++ .resume = samsung_lte_panel_resume, ++ ++ .driver = { ++ .name = "samsung_lte_panel", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init samsung_lte_panel_drv_init(void) ++{ ++ return omap_dss_register_driver(&samsung_lte_driver); ++} ++ ++static void __exit samsung_lte_panel_drv_exit(void) ++{ ++ omap_dss_unregister_driver(&samsung_lte_driver); ++} ++ ++module_init(samsung_lte_panel_drv_init); ++module_exit(samsung_lte_panel_drv_exit); ++MODULE_LICENSE("GPL"); +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0022-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-panel.patch b/extras/recipes-kernel/linux/linux-omap/base/0022-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-panel.patch new file mode 100644 index 00000000..c3029423 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0022-OMAP-DSS2-Add-support-for-LG-Philips-LB035Q02-panel.patch @@ -0,0 +1,299 @@ +From 93032782a4803072d7ab1e22da029325f8f3cf44 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 17 Dec 2009 15:05:30 -0800 +Subject: [PATCH 22/28] OMAP: DSS2: Add support for LG Philips LB035Q02 panel + +--- + drivers/video/omap2/displays/Kconfig | 12 + + drivers/video/omap2/displays/Makefile | 2 + + .../omap2/displays/panel-lgphilips-lb035q02.c | 244 ++++++++++++++++++++ + 3 files changed, 258 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 12327bb..48e872f 100644 +--- a/drivers/video/omap2/displays/Kconfig ++++ b/drivers/video/omap2/displays/Kconfig +@@ -7,6 +7,18 @@ 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 ++ help ++ LCD Panel used on Overo Palo43 ++ + config PANEL_SHARP_LS037V7DW01 + tristate "Sharp LS037V7DW01 LCD Panel" + depends on OMAP2_DSS +diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile +index aa38609..2fb1a57 100644 +--- a/drivers/video/omap2/displays/Makefile ++++ b/drivers/video/omap2/displays/Makefile +@@ -1,4 +1,6 @@ + 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 + obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.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..4ad709d +--- /dev/null ++++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +@@ -0,0 +1,244 @@ ++/* ++ * LCD panel driver for LG.Philips LB035Q02 ++ * ++ * Author: Steve Sakoman ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++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_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_power_on(struct omap_dss_device *dssdev) ++{ ++ int r; ++ ++ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) ++ return 0; ++ ++ r = omapdss_dpi_display_enable(dssdev); ++ if (r) ++ goto err0; ++ ++ if (dssdev->platform_enable) { ++ r = dssdev->platform_enable(dssdev); ++ if (r) ++ goto err1; ++ } ++ ++ /* 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 0; ++err1: ++ omapdss_dpi_display_disable(dssdev); ++err0: ++ return r; ++} ++ ++static void lb035q02_panel_power_off(struct omap_dss_device *dssdev) ++{ ++ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) ++ return; ++ ++ if (dssdev->platform_disable) ++ dssdev->platform_disable(dssdev); ++ ++ omapdss_dpi_display_disable(dssdev); ++} ++ ++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_panel_enable(struct omap_dss_device *dssdev) ++{ ++ int r = 0; ++ ++ r = lb035q02_panel_power_on(dssdev); ++ if (r) ++ return r; ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++} ++ ++static void lb035q02_panel_disable(struct omap_dss_device *dssdev) ++{ ++ lb035q02_panel_power_off(dssdev); ++ ++ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; ++} ++ ++static int lb035q02_panel_suspend(struct omap_dss_device *dssdev) ++{ ++ lb035q02_panel_disable(dssdev); ++ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; ++ return 0; ++} ++ ++static int lb035q02_panel_resume(struct omap_dss_device *dssdev) ++{ ++ int r; ++ ++ r = lb035q02_panel_power_on(dssdev); ++ if (r) ++ return r; ++ ++ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; ++ ++ return 0; ++} ++ ++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 r; ++ r = spi_register_driver(&lb035q02_spi_driver); ++ if (r != 0) ++ pr_err("lgphilips_lb035q02: Unable to register SPI driver: %d\n", r); ++ ++ r = omap_dss_register_driver(&lb035q02_driver); ++ if (r != 0) ++ pr_err("lgphilips_lb035q02: Unable to register panel driver: %d\n", r); ++ ++ return r; ++} ++ ++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.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0023-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch b/extras/recipes-kernel/linux/linux-omap/base/0023-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch new file mode 100644 index 00000000..12f7d7b0 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0023-OMAP-DSS2-add-bootarg-for-selecting-svideo-or-compos.patch @@ -0,0 +1,75 @@ +From f046a207183e3e338c7e851085265f0df95f4cc2 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Tue, 19 Jan 2010 21:19:15 -0800 +Subject: [PATCH 23/28] OMAP: DSS2: add bootarg for selecting svideo or composite for tv output + +also add pal-16 and ntsc-16 omapfb.mode settings for 16bpp +--- + drivers/video/omap2/dss/venc.c | 22 ++++++++++++++++++++++ + drivers/video/omap2/omapfb/omapfb-main.c | 10 +++++++++- + 2 files changed, 31 insertions(+), 1 deletions(-) + +diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c +index eff3505..e1f4aab 100644 +--- a/drivers/video/omap2/dss/venc.c ++++ b/drivers/video/omap2/dss/venc.c +@@ -87,6 +87,11 @@ + #define VENC_OUTPUT_TEST 0xC8 + #define VENC_DAC_B__DAC_C 0xC8 + ++static char *tv_connection; ++ ++module_param_named(tvcable, tv_connection, charp, 0); ++MODULE_PARM_DESC(tvcable, "TV connection type (svideo, composite)"); ++ + struct venc_config { + u32 f_control; + u32 vidout_ctrl; +@@ -459,6 +464,23 @@ static int venc_panel_probe(struct omap_dss_device *dssdev) + { + dssdev->panel.timings = omap_dss_pal_timings; + ++ /* Allow the TV output to be overriden */ ++ if (tv_connection) { ++ if (strcmp(tv_connection, "svideo") == 0) { ++ printk(KERN_INFO ++ "omapdss: tv output is svideo.\n"); ++ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO; ++ } else if (strcmp(tv_connection, "composite") == 0) { ++ printk(KERN_INFO ++ "omapdss: tv output is composite.\n"); ++ dssdev->phy.venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE; ++ } else { ++ printk(KERN_INFO ++ "omapdss: unsupported output type'%s'.\n", ++ tv_connection); ++ } ++ } ++ + return 0; + } + +diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c +index 6a704f1..7ee833f 100644 +--- a/drivers/video/omap2/omapfb/omapfb-main.c ++++ b/drivers/video/omap2/omapfb/omapfb-main.c +@@ -2036,7 +2036,15 @@ static int omapfb_mode_to_timings(const char *mode_str, + int r; + + #ifdef CONFIG_OMAP2_DSS_VENC +- if (strcmp(mode_str, "pal") == 0) { ++ if (strcmp(mode_str, "pal-16") == 0) { ++ *timings = omap_dss_pal_timings; ++ *bpp = 16; ++ return 0; ++ } else if (strcmp(mode_str, "ntsc-16") == 0) { ++ *timings = omap_dss_ntsc_timings; ++ *bpp = 16; ++ return 0; ++ } else if (strcmp(mode_str, "pal") == 0) { + *timings = omap_dss_pal_timings; + *bpp = 24; + return 0; +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0024-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch b/extras/recipes-kernel/linux/linux-omap/base/0024-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch new file mode 100644 index 00000000..f012a91a --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0024-ARM-OMAP2-mmc-twl4030-move-clock-input-selection-pri.patch @@ -0,0 +1,39 @@ +From 66bba5baf225a1420c734aa0268e7dd37fc3f73b Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Sun, 24 Jan 2010 09:33:56 -0800 +Subject: [PATCH 24/28] ARM: OMAP2: mmc-twl4030: move clock input selection prior to vcc test + +otherwise it is not executed on systems that use non-twl regulators +--- + arch/arm/mach-omap2/hsmmc.c | 14 ++++++-------- + 1 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c +index 34272e4..a74631d 100644 +--- a/arch/arm/mach-omap2/hsmmc.c ++++ b/arch/arm/mach-omap2/hsmmc.c +@@ -186,15 +186,13 @@ static void hsmmc23_before_set_reg(struct device *dev, int slot, + if (mmc->slots[0].remux) + mmc->slots[0].remux(dev, slot, power_on); + +- if (power_on) { +- /* Only MMC2 supports a CLKIN */ +- if (mmc->slots[0].internal_clock) { +- u32 reg; ++ /* Only MMC2 supports a CLKIN */ ++ if (mmc->slots[0].internal_clock) { ++ u32 reg; + +- reg = omap_ctrl_readl(control_devconf1_offset); +- reg |= OMAP2_MMCSDIO2ADPCLKISEL; +- omap_ctrl_writel(reg, control_devconf1_offset); +- } ++ reg = omap_ctrl_readl(control_devconf1_offset); ++ reg |= OMAP2_MMCSDIO2ADPCLKISEL; ++ omap_ctrl_writel(reg, control_devconf1_offset); + } + } + +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0025-RTC-add-support-for-backup-battery-recharge.patch b/extras/recipes-kernel/linux/linux-omap/base/0025-RTC-add-support-for-backup-battery-recharge.patch new file mode 100644 index 00000000..419e7648 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0025-RTC-add-support-for-backup-battery-recharge.patch @@ -0,0 +1,55 @@ +From ae08111e55d17183382dd06d161066adf9f80f3c Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Thu, 4 Feb 2010 12:26:22 -0800 +Subject: [PATCH 25/28] RTC: add support for backup battery recharge + +--- + drivers/rtc/rtc-twl.c | 25 +++++++++++++++++++++++++ + 1 files changed, 25 insertions(+), 0 deletions(-) + +diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c +index ed1b868..33a8598 100644 +--- a/drivers/rtc/rtc-twl.c ++++ b/drivers/rtc/rtc-twl.c +@@ -30,6 +30,23 @@ + + #include + ++/* ++ * PM_RECEIVER block register offsets (use TWL4030_MODULE_PM_RECEIVER) ++ */ ++#define REG_BB_CFG 0x12 ++ ++/* PM_RECEIVER BB_CFG bitfields */ ++#define BIT_PM_RECEIVER_BB_CFG_BBCHEN 0x10 ++#define BIT_PM_RECEIVER_BB_CFG_BBSEL 0x0C ++#define BIT_PM_RECEIVER_BB_CFG_BBSEL_2V5 0x00 ++#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V0 0x04 ++#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 0x08 ++#define BIT_PM_RECEIVER_BB_CFG_BBSEL_3v2 0x0c ++#define BIT_PM_RECEIVER_BB_CFG_BBISEL 0x03 ++#define BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA 0x00 ++#define BIT_PM_RECEIVER_BB_CFG_BBISEL_150UA 0x01 ++#define BIT_PM_RECEIVER_BB_CFG_BBISEL_500UA 0x02 ++#define BIT_PM_RECEIVER_BB_CFG_BBISEL_1MA 0x03 + + /* + * RTC block register offsets (use TWL_MODULE_RTC) +@@ -508,6 +525,14 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) + if (ret < 0) + goto out2; + ++ /* enable backup battery charging */ ++ /* use a conservative 25uA @ 3.1V */ ++ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, ++ BIT_PM_RECEIVER_BB_CFG_BBCHEN | ++ BIT_PM_RECEIVER_BB_CFG_BBSEL_3V1 | ++ BIT_PM_RECEIVER_BB_CFG_BBISEL_25UA, ++ REG_BB_CFG); ++ + return ret; + + out2: +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0026-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch b/extras/recipes-kernel/linux/linux-omap/base/0026-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch new file mode 100644 index 00000000..b002f288 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0026-ARM-OMAP-automatically-set-musb-mode-in-platform-dat.patch @@ -0,0 +1,49 @@ +From dd53a7c1ab8addfd2a943ea44b5ccc5700648323 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Wed, 24 Feb 2010 10:37:22 -0800 +Subject: [PATCH 26/28] ARM: OMAP: automatically set musb mode in platform data based on CONFIG options + +--- + arch/arm/mach-omap2/board-omap3beagle.c | 6 ++++++ + arch/arm/mach-omap2/board-overo.c | 6 ++++++ + 2 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c +index 9259780..ad0c1d8 100644 +--- a/arch/arm/mach-omap2/board-omap3beagle.c ++++ b/arch/arm/mach-omap2/board-omap3beagle.c +@@ -785,7 +785,13 @@ static struct omap_board_mux board_mux[] __initdata = { + + static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, ++#if defined(CONFIG_USB_MUSB_OTG) + .mode = MUSB_OTG, ++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) ++ .mode = MUSB_PERIPHERAL, ++#else ++ .mode = MUSB_HOST, ++#endif + .power = 100, + }; + +diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c +index 17f066a..b28a9d5 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -447,7 +447,13 @@ static struct omap_board_mux board_mux[] __initdata = { + + static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, ++#if defined(CONFIG_USB_MUSB_OTG) + .mode = MUSB_OTG, ++#elif defined(CONFIG_USB_GADGET_MUSB_HDRC) ++ .mode = MUSB_PERIPHERAL, ++#else ++ .mode = MUSB_HOST, ++#endif + .power = 100, + }; + +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0027-OMAP-DSS2-check-for-both-cpu-type-and-revision-rathe.patch b/extras/recipes-kernel/linux/linux-omap/base/0027-OMAP-DSS2-check-for-both-cpu-type-and-revision-rathe.patch new file mode 100644 index 00000000..8f672d9a --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0027-OMAP-DSS2-check-for-both-cpu-type-and-revision-rathe.patch @@ -0,0 +1,34 @@ +From ec3e66ef2e222feb0408f16a3498be1ea9b6a9c0 Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Mon, 10 May 2010 13:59:14 -0700 +Subject: [PATCH 27/28] OMAP: DSS2: check for both cpu type and revision, rather than just revision + +--- + drivers/video/omap2/dss/dispc.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c +index fa40fa5..133916a 100644 +--- a/drivers/video/omap2/dss/dispc.c ++++ b/drivers/video/omap2/dss/dispc.c +@@ -2101,7 +2101,7 @@ void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode) + static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp, + int vsw, int vfp, int vbp) + { +- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { ++ if (cpu_is_omap24xx() || (cpu_is_omap34xx() && omap_rev_lt_3_0())) { + if (hsw < 1 || hsw > 64 || + hfp < 1 || hfp > 256 || + hbp < 1 || hbp > 256 || +@@ -2134,7 +2134,7 @@ static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp, + { + u32 timing_h, timing_v; + +- if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) { ++ if (cpu_is_omap24xx() || (cpu_is_omap34xx() && omap_rev_lt_3_0())) { + timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) | + FLD_VAL(hbp-1, 27, 20); + +-- +1.6.6.1 + diff --git a/extras/recipes-kernel/linux/linux-omap/base/0028-OMAP-DSS2-Add-DSS2-support-for-Overo.patch b/extras/recipes-kernel/linux/linux-omap/base/0028-OMAP-DSS2-Add-DSS2-support-for-Overo.patch new file mode 100644 index 00000000..ff2ab556 --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/base/0028-OMAP-DSS2-Add-DSS2-support-for-Overo.patch @@ -0,0 +1,355 @@ +From 9b2bfa418f2e1b7ed3e210cb7cba3cdd67f9925f Mon Sep 17 00:00:00 2001 +From: Steve Sakoman +Date: Fri, 18 Dec 2009 06:39:24 -0800 +Subject: [PATCH 28/28] OMAP: DSS2: Add DSS2 support for Overo + +--- + arch/arm/mach-omap2/board-overo.c | 238 +++++++++++++++++++++++++++++++------ + 1 files changed, 204 insertions(+), 34 deletions(-) + +diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c +index b28a9d5..8a44c17 100644 +--- a/arch/arm/mach-omap2/board-overo.c ++++ b/arch/arm/mach-omap2/board-overo.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -41,10 +42,13 @@ + + #include + #include ++#include + #include + #include + #include + #include ++#include ++#include + #include + + #include "mux.h" +@@ -68,8 +72,6 @@ + #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ + defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + +-#include +-#include + #include + + static struct omap2_mcspi_device_config ads7846_mcspi_config = { +@@ -94,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) && +@@ -115,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 +@@ -233,6 +220,139 @@ 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 struct omap_dss_device overo_tv_device = { ++ .name = "tv", ++ .driver_name = "venc", ++ .type = OMAP_DISPLAY_TYPE_VENC, ++ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, ++}; ++ ++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, ++ .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, ++ .platform_enable = overo_panel_enable_lcd, ++ .platform_disable = overo_panel_disable_lcd, ++}; ++#endif ++ ++static struct omap_dss_device *overo_dss_devices[] = { ++ &overo_dvi_device, ++ &overo_tv_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 = ++ REGULATOR_SUPPLY("vdda_dac", "omapdss"); ++ ++static struct regulator_consumer_supply overo_vdds_dsi_supply = ++ REGULATOR_SUPPLY("vdds_dsi", "omapdss"); ++ + static struct mtd_partition overo_nand_partitions[] = { + { + .name = "xloader", +@@ -358,6 +478,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, + }; +@@ -367,8 +518,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, + }; +@@ -381,6 +530,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[] = { +@@ -401,23 +552,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_infrastructure(); + omap2_init_common_devices(mt46h32m32lf6_sdrc_params, + mt46h32m32lf6_sdrc_params); +@@ -425,7 +594,7 @@ static void __init overo_init_irq(void) + } + + static struct platform_device *overo_devices[] __initdata = { +- &overo_lcd_device, ++ &overo_dss_device, + }; + + static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { +@@ -466,8 +635,9 @@ static void __init overo_init(void) + overo_flash_init(); + usb_musb_init(&musb_board_data); + 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_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); +@@ -510,7 +680,7 @@ static void __init overo_init(void) + "OVERO_GPIO_USBH_CPEN\n"); + } + +-MACHINE_START(OVERO, "Gumstix Overo") ++MACHINE_START(OVERO, "Gumstsix Overo") + .boot_params = 0x80000100, + .map_io = omap3_map_io, + .reserve = omap_reserve, +-- +1.6.6.1 + -- cgit v1.2.3-54-g00ecf