aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-07-11 17:06:35 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-11 17:06:35 -0400
commit8600fb68cfa8f89e23cf872efb87fec641cc747d (patch)
tree60ec7cbf9f2f09fd97f1895cc4b3854414fe1db9 /arch/arm/mach-shmobile
parent8533bae35becc0b18dc5a6c59ead36dee57cfb47 (diff)
parent70523b4e57cb6eeb1da7c8ebf19df855221825ad (diff)
Merge branch 'renesas-armadillo' into renesas-board
* renesas-armadillo: ARM: mach-shmobile: armadillo800eva: defconfig Allow use of armhf userspace ARM: shmobile: armadillo800eva: A3SP domain includes USB ARM: shmobile: armadillo800eva: A4LC domain includes LCDC ARM: shmobile: armadillo800eva: USB Func enables external IRQ mode ARM: mach-shmobile: add fixed voltage regulators to armadillo800eva ARM: shmobile: use common extra gpio functions on armadillo800eva ARM: shmobile: armadillo800eva: enable DMAEngine on USB ARM: shmobile: armadillo800eva: enable DMAEngine on SDHI ARM: shmobile: armadillo800eva: enable DMAEngine on FSI ARM: shmobile: armadillo800eva: enable FSI-HDMI sound ARM: shmobile: armadillo800eva: enable FSI-WM8978 sound Conflicts: arch/arm/mach-shmobile/Kconfig
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/Kconfig1
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c243
2 files changed, 234 insertions, 10 deletions
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 0168382d3cba..4cacc2d22fbe 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -114,6 +114,7 @@ config MACH_ARMADILLO800EVA
114 select ARCH_REQUIRE_GPIOLIB 114 select ARCH_REQUIRE_GPIOLIB
115 select USE_OF 115 select USE_OF
116 select REGULATOR_FIXED_VOLTAGE if REGULATOR 116 select REGULATOR_FIXED_VOLTAGE if REGULATOR
117 select SND_SOC_WM8978 if SND_SIMPLE_CARD
117 118
118config MACH_MARZEN 119config MACH_MARZEN
119 bool "MARZEN board" 120 bool "MARZEN board"
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index a513ebee98d5..cf10f92856dc 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -28,6 +28,8 @@
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/gpio_keys.h> 30#include <linux/gpio_keys.h>
31#include <linux/regulator/fixed.h>
32#include <linux/regulator/machine.h>
31#include <linux/sh_eth.h> 33#include <linux/sh_eth.h>
32#include <linux/videodev2.h> 34#include <linux/videodev2.h>
33#include <linux/usb/renesas_usbhs.h> 35#include <linux/usb/renesas_usbhs.h>
@@ -49,6 +51,8 @@
49#include <asm/hardware/cache-l2x0.h> 51#include <asm/hardware/cache-l2x0.h>
50#include <video/sh_mobile_lcdc.h> 52#include <video/sh_mobile_lcdc.h>
51#include <video/sh_mobile_hdmi.h> 53#include <video/sh_mobile_hdmi.h>
54#include <sound/sh_fsi.h>
55#include <sound/simple_card.h>
52 56
53/* 57/*
54 * CON1 Camera Module 58 * CON1 Camera Module
@@ -112,6 +116,14 @@
112 */ 116 */
113 117
114/* 118/*
119 * FSI-WM8978
120 *
121 * this command is required when playback.
122 *
123 * # amixer set "Headphone" 50
124 */
125
126/*
115 * USB function 127 * USB function
116 * 128 *
117 * When you use USB Function, 129 * When you use USB Function,
@@ -121,14 +133,8 @@
121 * These are a little bit complex. 133 * These are a little bit complex.
122 * see 134 * see
123 * usbhsf_power_ctrl() 135 * usbhsf_power_ctrl()
124 *
125 * CAUTION
126 *
127 * It uses autonomy mode for USB hotplug at this point
128 * (= usbhs_private.platform_callback.get_vbus is NULL),
129 * since we don't know what's happen on PM control
130 * on this workaround.
131 */ 136 */
137#define IRQ7 evt2irq(0x02e0)
132#define USBCR1 0xe605810a 138#define USBCR1 0xe605810a
133#define USBH 0xC6700000 139#define USBH 0xC6700000
134#define USBH_USBCTR 0x10834 140#define USBH_USBCTR 0x10834
@@ -208,6 +214,20 @@ static void usbhsf_power_ctrl(struct platform_device *pdev,
208 } 214 }
209} 215}
210 216
217static int usbhsf_get_vbus(struct platform_device *pdev)
218{
219 return gpio_get_value(GPIO_PORT209);
220}
221
222static irqreturn_t usbhsf_interrupt(int irq, void *data)
223{
224 struct platform_device *pdev = data;
225
226 renesas_usbhs_call_notify_hotplug(pdev);
227
228 return IRQ_HANDLED;
229}
230
211static void usbhsf_hardware_exit(struct platform_device *pdev) 231static void usbhsf_hardware_exit(struct platform_device *pdev)
212{ 232{
213 struct usbhsf_private *priv = usbhsf_get_priv(pdev); 233 struct usbhsf_private *priv = usbhsf_get_priv(pdev);
@@ -231,11 +251,14 @@ static void usbhsf_hardware_exit(struct platform_device *pdev)
231 priv->host = NULL; 251 priv->host = NULL;
232 priv->func = NULL; 252 priv->func = NULL;
233 priv->usbh_base = NULL; 253 priv->usbh_base = NULL;
254
255 free_irq(IRQ7, pdev);
234} 256}
235 257
236static int usbhsf_hardware_init(struct platform_device *pdev) 258static int usbhsf_hardware_init(struct platform_device *pdev)
237{ 259{
238 struct usbhsf_private *priv = usbhsf_get_priv(pdev); 260 struct usbhsf_private *priv = usbhsf_get_priv(pdev);
261 int ret;
239 262
240 priv->phy = clk_get(&pdev->dev, "phy"); 263 priv->phy = clk_get(&pdev->dev, "phy");
241 priv->usb24 = clk_get(&pdev->dev, "usb24"); 264 priv->usb24 = clk_get(&pdev->dev, "usb24");
@@ -255,6 +278,14 @@ static int usbhsf_hardware_init(struct platform_device *pdev)
255 return -EIO; 278 return -EIO;
256 } 279 }
257 280
281 ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE,
282 dev_name(&pdev->dev), pdev);
283 if (ret) {
284 dev_err(&pdev->dev, "request_irq err\n");
285 return ret;
286 }
287 irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH);
288
258 /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */ 289 /* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
259 clk_set_rate(priv->usb24, 290 clk_set_rate(priv->usb24,
260 clk_get_rate(clk_get_parent(priv->usb24))); 291 clk_get_rate(clk_get_parent(priv->usb24)));
@@ -266,6 +297,7 @@ static struct usbhsf_private usbhsf_private = {
266 .info = { 297 .info = {
267 .platform_callback = { 298 .platform_callback = {
268 .get_id = usbhsf_get_id, 299 .get_id = usbhsf_get_id,
300 .get_vbus = usbhsf_get_vbus,
269 .hardware_init = usbhsf_hardware_init, 301 .hardware_init = usbhsf_hardware_init,
270 .hardware_exit = usbhsf_hardware_exit, 302 .hardware_exit = usbhsf_hardware_exit,
271 .power_ctrl = usbhsf_power_ctrl, 303 .power_ctrl = usbhsf_power_ctrl,
@@ -273,6 +305,8 @@ static struct usbhsf_private usbhsf_private = {
273 .driver_param = { 305 .driver_param = {
274 .buswait_bwait = 5, 306 .buswait_bwait = 5,
275 .detection_delay = 5, 307 .detection_delay = 5,
308 .d0_rx_id = SHDMA_SLAVE_USBHS_RX,
309 .d1_tx_id = SHDMA_SLAVE_USBHS_TX,
276 }, 310 },
277 } 311 }
278}; 312};
@@ -508,6 +542,17 @@ static struct platform_device gpio_keys_device = {
508 }, 542 },
509}; 543};
510 544
545/* Fixed 3.3V regulator to be used by SDHI0, SDHI1, MMCIF */
546static struct regulator_consumer_supply fixed3v3_power_consumers[] =
547{
548 REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
549 REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
550 REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
551 REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
552 REGULATOR_SUPPLY("vmmc", "sh_mmcif"),
553 REGULATOR_SUPPLY("vqmmc", "sh_mmcif"),
554};
555
511/* SDHI0 */ 556/* SDHI0 */
512/* 557/*
513 * FIXME 558 * FIXME
@@ -519,6 +564,8 @@ static struct platform_device gpio_keys_device = {
519 */ 564 */
520#define IRQ31 evt2irq(0x33E0) 565#define IRQ31 evt2irq(0x33E0)
521static struct sh_mobile_sdhi_info sdhi0_info = { 566static struct sh_mobile_sdhi_info sdhi0_info = {
567 .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
568 .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
522 .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\ 569 .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\
523 MMC_CAP_NEEDS_POLL, 570 MMC_CAP_NEEDS_POLL,
524 .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 571 .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -559,6 +606,8 @@ static struct platform_device sdhi0_device = {
559 606
560/* SDHI1 */ 607/* SDHI1 */
561static struct sh_mobile_sdhi_info sdhi1_info = { 608static struct sh_mobile_sdhi_info sdhi1_info = {
609 .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
610 .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
562 .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ, 611 .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
563 .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 612 .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
564 .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, 613 .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
@@ -714,12 +763,128 @@ static struct platform_device ceu0_device = {
714 }, 763 },
715}; 764};
716 765
766/* FSI */
767static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
768{
769 struct clk *fsib;
770 int ret;
771
772 /* it support 48KHz only */
773 if (48000 != rate)
774 return -EINVAL;
775
776 fsib = clk_get(dev, "ickb");
777 if (IS_ERR(fsib))
778 return -EINVAL;
779
780 if (enable) {
781 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
782 clk_enable(fsib);
783 } else {
784 ret = 0;
785 clk_disable(fsib);
786 }
787
788 clk_put(fsib);
789
790 return ret;
791}
792
793static struct sh_fsi_platform_info fsi_info = {
794 /* FSI-WM8978 */
795 .port_a = {
796 .tx_id = SHDMA_SLAVE_FSIA_TX,
797 },
798 /* FSI-HDMI */
799 .port_b = {
800 .flags = SH_FSI_FMT_SPDIF |
801 SH_FSI_ENABLE_STREAM_MODE,
802 .set_rate = fsi_hdmi_set_rate,
803 .tx_id = SHDMA_SLAVE_FSIB_TX,
804 }
805};
806
807static struct resource fsi_resources[] = {
808 [0] = {
809 .name = "FSI",
810 .start = 0xfe1f0000,
811 .end = 0xfe1f8400 - 1,
812 .flags = IORESOURCE_MEM,
813 },
814 [1] = {
815 .start = evt2irq(0x1840),
816 .flags = IORESOURCE_IRQ,
817 },
818};
819
820static struct platform_device fsi_device = {
821 .name = "sh_fsi2",
822 .id = -1,
823 .num_resources = ARRAY_SIZE(fsi_resources),
824 .resource = fsi_resources,
825 .dev = {
826 .platform_data = &fsi_info,
827 },
828};
829
830/* FSI-WM8978 */
831static struct asoc_simple_dai_init_info fsi_wm8978_init_info = {
832 .fmt = SND_SOC_DAIFMT_I2S,
833 .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF,
834 .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
835 .sysclk = 12288000,
836};
837
838static struct asoc_simple_card_info fsi_wm8978_info = {
839 .name = "wm8978",
840 .card = "FSI2A-WM8978",
841 .cpu_dai = "fsia-dai",
842 .codec = "wm8978.0-001a",
843 .platform = "sh_fsi2",
844 .codec_dai = "wm8978-hifi",
845 .init = &fsi_wm8978_init_info,
846};
847
848static struct platform_device fsi_wm8978_device = {
849 .name = "asoc-simple-card",
850 .id = 0,
851 .dev = {
852 .platform_data = &fsi_wm8978_info,
853 },
854};
855
856/* FSI-HDMI */
857static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = {
858 .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM,
859};
860
861static struct asoc_simple_card_info fsi2_hdmi_info = {
862 .name = "HDMI",
863 .card = "FSI2B-HDMI",
864 .cpu_dai = "fsib-dai",
865 .codec = "sh-mobile-hdmi",
866 .platform = "sh_fsi2",
867 .codec_dai = "sh_mobile_hdmi-hifi",
868 .init = &fsi2_hdmi_init_info,
869};
870
871static struct platform_device fsi_hdmi_device = {
872 .name = "asoc-simple-card",
873 .id = 1,
874 .dev = {
875 .platform_data = &fsi2_hdmi_info,
876 },
877};
878
717/* I2C */ 879/* I2C */
718static struct i2c_board_info i2c0_devices[] = { 880static struct i2c_board_info i2c0_devices[] = {
719 { 881 {
720 I2C_BOARD_INFO("st1232-ts", 0x55), 882 I2C_BOARD_INFO("st1232-ts", 0x55),
721 .irq = evt2irq(0x0340), 883 .irq = evt2irq(0x0340),
722 }, 884 },
885 {
886 I2C_BOARD_INFO("wm8978", 0x1a),
887 },
723}; 888};
724 889
725/* 890/*
@@ -735,6 +900,9 @@ static struct platform_device *eva_devices[] __initdata = {
735 &hdmi_lcdc_device, 900 &hdmi_lcdc_device,
736 &camera_device, 901 &camera_device,
737 &ceu0_device, 902 &ceu0_device,
903 &fsi_device,
904 &fsi_hdmi_device,
905 &fsi_wm8978_device,
738}; 906};
739 907
740static void __init eva_clock_init(void) 908static void __init eva_clock_init(void)
@@ -742,10 +910,14 @@ static void __init eva_clock_init(void)
742 struct clk *system = clk_get(NULL, "system_clk"); 910 struct clk *system = clk_get(NULL, "system_clk");
743 struct clk *xtal1 = clk_get(NULL, "extal1"); 911 struct clk *xtal1 = clk_get(NULL, "extal1");
744 struct clk *usb24s = clk_get(NULL, "usb24s"); 912 struct clk *usb24s = clk_get(NULL, "usb24s");
913 struct clk *fsibck = clk_get(NULL, "fsibck");
914 struct clk *fsib = clk_get(&fsi_device.dev, "ickb");
745 915
746 if (IS_ERR(system) || 916 if (IS_ERR(system) ||
747 IS_ERR(xtal1) || 917 IS_ERR(xtal1) ||
748 IS_ERR(usb24s)) { 918 IS_ERR(usb24s) ||
919 IS_ERR(fsibck) ||
920 IS_ERR(fsib)) {
749 pr_err("armadillo800eva board clock init failed\n"); 921 pr_err("armadillo800eva board clock init failed\n");
750 goto clock_error; 922 goto clock_error;
751 } 923 }
@@ -756,6 +928,11 @@ static void __init eva_clock_init(void)
756 /* usb24s use extal1 (= system) clock (= 24MHz) */ 928 /* usb24s use extal1 (= system) clock (= 24MHz) */
757 clk_set_parent(usb24s, system); 929 clk_set_parent(usb24s, system);
758 930
931 /* FSIBCK is 12.288MHz, and it is parent of FSI-B */
932 clk_set_parent(fsib, fsibck);
933 clk_set_rate(fsibck, 12288000);
934 clk_set_rate(fsib, 12288000);
935
759clock_error: 936clock_error:
760 if (!IS_ERR(system)) 937 if (!IS_ERR(system))
761 clk_put(system); 938 clk_put(system);
@@ -763,14 +940,23 @@ clock_error:
763 clk_put(xtal1); 940 clk_put(xtal1);
764 if (!IS_ERR(usb24s)) 941 if (!IS_ERR(usb24s))
765 clk_put(usb24s); 942 clk_put(usb24s);
943 if (!IS_ERR(fsibck))
944 clk_put(fsibck);
945 if (!IS_ERR(fsib))
946 clk_put(fsib);
766} 947}
767 948
768/* 949/*
769 * board init 950 * board init
770 */ 951 */
952#define GPIO_PORT7CR 0xe6050007
953#define GPIO_PORT8CR 0xe6050008
771static void __init eva_init(void) 954static void __init eva_init(void)
772{ 955{
773 eva_clock_init(); 956 struct platform_device *usb = NULL;
957
958 regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
959 ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
774 960
775 r8a7740_pinmux_init(); 961 r8a7740_pinmux_init();
776 r8a7740_meram_workaround(); 962 r8a7740_meram_workaround();
@@ -854,8 +1040,19 @@ static void __init eva_init(void)
854 /* USB Host */ 1040 /* USB Host */
855 } else { 1041 } else {
856 /* USB Func */ 1042 /* USB Func */
857 gpio_request(GPIO_FN_VBUS, NULL); 1043 /*
1044 * A1 chip has 2 IRQ7 pin and it was controled by MSEL register.
1045 * OTOH, usbhs interrupt needs its value (HI/LOW) to decide
1046 * USB connection/disconnection (usbhsf_get_vbus()).
1047 * This means we needs to select GPIO_FN_IRQ7_PORT209 first,
1048 * and select GPIO_PORT209 here
1049 */
1050 gpio_request(GPIO_FN_IRQ7_PORT209, NULL);
1051 gpio_request(GPIO_PORT209, NULL);
1052 gpio_direction_input(GPIO_PORT209);
1053
858 platform_device_register(&usbhsf_device); 1054 platform_device_register(&usbhsf_device);
1055 usb = &usbhsf_device;
859 } 1056 }
860 1057
861 /* SDHI0 */ 1058 /* SDHI0 */
@@ -916,6 +1113,25 @@ static void __init eva_init(void)
916 gpio_direction_output(GPIO_PORT172, 1); 1113 gpio_direction_output(GPIO_PORT172, 1);
917 gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */ 1114 gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */
918 1115
1116 /* FSI-WM8978 */
1117 gpio_request(GPIO_FN_FSIAIBT, NULL);
1118 gpio_request(GPIO_FN_FSIAILR, NULL);
1119 gpio_request(GPIO_FN_FSIAOMC, NULL);
1120 gpio_request(GPIO_FN_FSIAOSLD, NULL);
1121 gpio_request(GPIO_FN_FSIAISLD_PORT5, NULL);
1122
1123 gpio_request(GPIO_PORT7, NULL);
1124 gpio_request(GPIO_PORT8, NULL);
1125 gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */
1126 gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */
1127
1128 /* FSI-HDMI */
1129 gpio_request(GPIO_FN_FSIBCK, NULL);
1130
1131 /* HDMI */
1132 gpio_request(GPIO_FN_HDMI_HPD, NULL);
1133 gpio_request(GPIO_FN_HDMI_CEC, NULL);
1134
919 /* 1135 /*
920 * CAUTION 1136 * CAUTION
921 * 1137 *
@@ -962,6 +1178,13 @@ static void __init eva_init(void)
962 1178
963 platform_add_devices(eva_devices, 1179 platform_add_devices(eva_devices,
964 ARRAY_SIZE(eva_devices)); 1180 ARRAY_SIZE(eva_devices));
1181
1182 eva_clock_init();
1183
1184 rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device);
1185 rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device);
1186 if (usb)
1187 rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb);
965} 1188}
966 1189
967static void __init eva_earlytimer_init(void) 1190static void __init eva_earlytimer_init(void)