From sshtylyov at mvista.com Fri Oct 1 05:48:37 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 01 Oct 2010 14:48:37 +0400 Subject: [PATCH v1] davinci: sound support for Omapl138-Hawkboard In-Reply-To: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> References: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CA5BC85.9000807@mvista.com> Hello. On 01-10-2010 4:50, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > Hi caglar > Please check this patch, I rebase your Audio patch to > the latest RC from Kernel development tree for TI DaVinci > I have tested it and it works perfect with ALSA utils. > I will rebase some of your patches to the latest rc > Please give me feedback and sign off if you want. I think this paragraph should be under ---. > This patch adds sound support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez > --- > Notes: > This patch is based on > davinci: Initial support for Omapl138-Hawkboard patch > from Kernel development tree for TI DaVinci family of processors. > This patch works with da8xx_omapl_defconfig > In order to test it select in menuconfig like insmodule > Sound card support ---> > Advanced Linux Sound Architecture ---> > ALSA for SoC audio support ---> > SoC Audio for the TI DAVINCI chip > SoC Audio support for DA850/OMAP-L138 > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 105 +++++++++++++++++++++++++++ > arch/arm/mach-davinci/da850.c | 2 +- > sound/soc/davinci/Kconfig | 4 +- > sound/soc/davinci/davinci-evm.c | 6 +- > 4 files changed, 112 insertions(+), 5 deletions(-) > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index fd1f458..d752244 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > +/* > + * The following EDMA channels/slots are not being used by drivers (for > + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence > + * they are being reserved for codecs on the DSP side. > + */ > +static const s16 da850_dma0_rsv_chans[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma0_rsv_slots[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 50}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_chans[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_slots[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 90}, > + {-1, -1} > +}; > + > +static struct edma_rsv_info da850_edma_cc0_rsv = { > + .rsv_chans = da850_dma0_rsv_chans, > + .rsv_slots = da850_dma0_rsv_slots, > +}; > + > +static struct edma_rsv_info da850_edma_cc1_rsv = { > + .rsv_chans = da850_dma1_rsv_chans, > + .rsv_slots = da850_dma1_rsv_slots, > +}; > + > +static struct edma_rsv_info *da850_edma_rsv[2] = { > + &da850_edma_cc0_rsv, > + &da850_edma_cc1_rsv, > +}; > + Well, I think the above should belongs to the separate EDMA suppport patch... > @@ -79,6 +161,29 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + > + ret = da850_register_edma(da850_edma_rsv); > + if (ret) > + pr_warning("hawk_init: edma registration failed: %d\n", > + ret); This too. > + da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > + > + Too many emoty lines... > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 63916b9..f033a0a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { > const short da850_mcasp_pins[] __initdata = { > DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, > DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, > - DA850_AXR_11, DA850_AXR_12, > + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, Should probably be in a separate patch.... > -1 > }; > diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig > index 6bbf001..cd29c81 100644 > --- a/sound/soc/davinci/Kconfig > +++ b/sound/soc/davinci/Kconfig > @@ -76,8 +76,8 @@ config SND_DA830_SOC_EVM > DA830/OMAP-L137 EVM > > config SND_DA850_SOC_EVM > - tristate "SoC Audio support for DA850/OMAP-L138 EVM" > - depends on SND_DAVINCI_SOC&& MACH_DAVINCI_DA850_EVM > + tristate "SoC Audio support for DA850/OMAP-L138 EVM / Hawkboard" > + depends on SND_DAVINCI_SOC&& (MACH_DAVINCI_DA850_EVM || MACH_OMAPL138_HAWKBOARD) > select SND_DAVINCI_SOC_MCASP > select SND_SOC_TLV320AIC3X > help > diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c > index 97f74d6..73093eb 100644 > --- a/sound/soc/davinci/davinci-evm.c > +++ b/sound/soc/davinci/davinci-evm.c > @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, > sysclk = 12288000; > > else if (machine_is_davinci_da830_evm() || > - machine_is_davinci_da850_evm()) > + machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) > sysclk = 24576000; > > else > @@ -311,7 +312,8 @@ static int __init evm_init(void) > } else if (machine_is_davinci_da830_evm()) { > evm_snd_dev_data =&da830_evm_snd_devdata; > index = 1; > - } else if (machine_is_davinci_da850_evm()) { > + } else if (machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) { > evm_snd_dev_data =&da850_evm_snd_devdata; > index = 0; > } else The sound/soc/ part should surely be in a sperate patch... WBR, Sergei From sshtylyov at mvista.com Fri Oct 1 05:50:38 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 01 Oct 2010 14:50:38 +0400 Subject: [PATCH v1] davinci: sound support for Omapl138-Hawkboard In-Reply-To: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> References: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CA5BCFE.8070103@mvista.com> On 01-10-2010 4:50, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > Hi caglar > Please check this patch, I rebase your Audio patch to > the latest RC from Kernel development tree for TI DaVinci > I have tested it and it works perfect with ALSA utils. > I will rebase some of your patches to the latest rc > Please give me feedback and sign off if you want. > This patch adds sound support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index fd1f458..d752244 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -79,6 +161,29 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + > + ret = da850_register_edma(da850_edma_rsv); > + if (ret) > + pr_warning("hawk_init: edma registration failed: %d\n", > + ret); > + > + i2c_register_board_info(1, omapl138_hawk_i2c_devices, > + ARRAY_SIZE(omapl138_hawk_i2c_devices)); > + > + ret = da8xx_register_i2c(0,&omapl138_hawk_i2c_0_pdata); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "i2c0 registration failed: %d\n", > + ret); Please align the above two lines. And I guess they really could be one line.. > + > + ret = davinci_cfg_reg_list(da850_mcasp_pins); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "mcasp mux setup failed: %d\n", > + ret); Same here... WBR, Sergei From sshtylyov at mvista.com Fri Oct 1 06:03:23 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 01 Oct 2010 15:03:23 +0400 Subject: [[RFC]PATCH v1] davinci: VGA support for Omapl138-Hawkboard In-Reply-To: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> References: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CA5BFFB.8060608@mvista.com> Hello. On 01-10-2010 5:15, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds VGA support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index d752244..ff009ad 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -183,6 +183,11 @@ static __init void omapl138_hawk_init(void) > ret); > da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > > + ret = da8xx_register_lcdc(&vga_monitor_pdata); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "lcdc registration failed: %d\n", > + ret); Please align the above two lines. I suspect that could fit on one line too. > diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c > index 9eec630..ad6fac2 100644 > --- a/arch/arm/mach-davinci/devices-da8xx.c > +++ b/arch/arm/mach-davinci/devices-da8xx.c > @@ -528,6 +528,12 @@ struct da8xx_lcdc_platform_data sharp_lk043t1dg01_pdata = { > .type = "Sharp_LK043T1DG01", > }; > > +struct da8xx_lcdc_platform_data vga_monitor_pdata = { > + .manu_name = "vga_mon", > + .controller_data = &lcd_cfg, > + .type = "VGA_Monitor", > +}; > + Sigh, this is a bad place for the platform data -- the platform data belongs to the board files. [...] > diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c > index cad7d45..eea7264 100644 > --- a/drivers/video/da8xx-fb.c > +++ b/drivers/video/da8xx-fb.c > @@ -212,6 +212,21 @@ static struct da8xx_panel known_lcd_panels[] = { > .pxl_clk = 7833600, > .invert_pxl_clk = 0, > }, > + > + /* CRT Monitor or LCD Screen */ > + [2] = { > + .name = "VGA_Monitor", > + .width = 640, > + .height = 480, > + .hfp = 48, > + .hbp = 48, > + .hsw = 63, > + .vfp = 11, > + .vbp = 31, > + .vsw = 1, > + .pxl_clk = 25000000, > + .invert_pxl_clk = 1, > + }, > }; > > /* Enable the Raster Engine of the LCD Controller */ The drivers/video/ part should be in a separate patch. WBR, Sergei From caglarakyuz at gmail.com Fri Oct 1 06:57:22 2010 From: caglarakyuz at gmail.com (Caglar Akyuz) Date: Fri, 1 Oct 2010 14:57:22 +0300 Subject: [[RFC]PATCH v1] davinci: VGA support for Omapl138-Hawkboard In-Reply-To: <4CA5BFFB.8060608@mvista.com> References: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> <4CA5BFFB.8060608@mvista.com> Message-ID: <201010011457.22959.caglarakyuz@gmail.com> On Friday 01 October 2010 02:03:23 pm Sergei Shtylyov wrote: > Hello. > > On 01-10-2010 5:15, vm.rod25 at gmail.com wrote: > > From: Victor Rodriguez > > > > This patch adds VGA support for the Hawkboard-L138 system > > It is under the machine name "omapl138_hawkboard". > > This system is based on the da850 davinci CPU architecture. > > > > Signed-off-by: Victor Rodriguez > > [...] > > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > > b/arch/arm/mach-davinci/board-omapl138-hawk.c index d752244..ff009ad > > 100644 > > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > @@ -183,6 +183,11 @@ static __init void omapl138_hawk_init(void) > > ret); > > da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > > > > + ret = da8xx_register_lcdc(&vga_monitor_pdata); > > + if (ret) > > + pr_warning("omapl138_hawk_init: " > > + "lcdc registration failed: %d\n", > > + ret); > > Please align the above two lines. I suspect that could fit on one line > too. > > > diff --git a/arch/arm/mach-davinci/devices-da8xx.c > > b/arch/arm/mach-davinci/devices-da8xx.c index 9eec630..ad6fac2 100644 > > --- a/arch/arm/mach-davinci/devices-da8xx.c > > +++ b/arch/arm/mach-davinci/devices-da8xx.c > > @@ -528,6 +528,12 @@ struct da8xx_lcdc_platform_data > > sharp_lk043t1dg01_pdata = { .type = "Sharp_LK043T1DG01", > > }; > > > > +struct da8xx_lcdc_platform_data vga_monitor_pdata = { > > + .manu_name = "vga_mon", > > + .controller_data = &lcd_cfg, > > + .type = "VGA_Monitor", > > +}; > > + > > Sigh, this is a bad place for the platform data -- the platform data > belongs to the board files. Indeed. Unfortunately lcd_cfg is statically defined in this file, I guess that's why this is here at the moment. Actually I prepared a patch to register display panels with fb driver, I would prefer if this does not goes in as is. Otherwise, we need to patch kernel for every panel/resolution combination users might have. Regards, Caglar > > [...] > > > diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c > > index cad7d45..eea7264 100644 > > --- a/drivers/video/da8xx-fb.c > > +++ b/drivers/video/da8xx-fb.c > > @@ -212,6 +212,21 @@ static struct da8xx_panel known_lcd_panels[] = { > > .pxl_clk = 7833600, > > .invert_pxl_clk = 0, > > }, > > + > > + /* CRT Monitor or LCD Screen */ > > + [2] = { > > + .name = "VGA_Monitor", > > + .width = 640, > > + .height = 480, > > + .hfp = 48, > > + .hbp = 48, > > + .hsw = 63, > > + .vfp = 11, > > + .vbp = 31, > > + .vsw = 1, > > + .pxl_clk = 25000000, > > + .invert_pxl_clk = 1, > > + }, > > }; > > > > /* Enable the Raster Engine of the LCD Controller */ > > The drivers/video/ part should be in a separate patch. > > WBR, Sergei > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > From caglarakyuz at gmail.com Fri Oct 1 07:08:26 2010 From: caglarakyuz at gmail.com (Caglar Akyuz) Date: Fri, 1 Oct 2010 15:08:26 +0300 Subject: [PATCH v1] davinci: sound support for Omapl138-Hawkboard In-Reply-To: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> References: <1285894245-26215-1-git-send-email-vm.rod25@gmail.com> Message-ID: <201010011508.27014.caglarakyuz@gmail.com> On Friday 01 October 2010 03:50:45 am vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > Hi caglar > > Please check this patch, I rebase your Audio patch to > the latest RC from Kernel development tree for TI DaVinci > I have tested it and it works perfect with ALSA utils. > I will rebase some of your patches to the latest rc > Please give me feedback and sign off if you want. > I think this patch should be submitted to alsa list as well... > This patch adds sound support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > > Signed-off-by: Victor Rodriguez > --- > Notes: > > This patch is based on > davinci: Initial support for Omapl138-Hawkboard patch > from Kernel development tree for TI DaVinci family of processors. > This patch works with da8xx_omapl_defconfig > > In order to test it select in menuconfig like insmodule > Sound card support ---> > Advanced Linux Sound Architecture ---> > ALSA for SoC audio support ---> > SoC Audio for the TI DAVINCI chip > SoC Audio support for DA850/OMAP-L138 > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 105 > +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | > 2 +- > sound/soc/davinci/Kconfig | 4 +- > sound/soc/davinci/davinci-evm.c | 6 +- > 4 files changed, 112 insertions(+), 5 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c index fd1f458..d752244 > 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -69,6 +70,87 @@ static int __init omapl138_hawk_config_emac(void) > } > device_initcall(omapl138_hawk_config_emac); > > +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { > + { > + I2C_BOARD_INFO("tlv320aic3x", 0x18), > + }, > +}; > + > +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { > + .bus_freq = 100, /* kHz */ > + .bus_delay = 0, /* usec */ > +}; > + > +/* davinci da850 evm audio machine driver */ > +static u8 da850_iis_serializer_direction[] = { > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, > +}; > + > +static struct snd_platform_data omapl138_hawk_snd_data = { > + .tx_dma_offset = 0x2000, > + .rx_dma_offset = 0x2000, > + .op_mode = DAVINCI_MCASP_IIS_MODE, > + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), > + .tdm_slots = 2, > + .serial_dir = da850_iis_serializer_direction, > + .asp_chan_q = EVENTQ_1, > + .version = MCASP_VERSION_2, > + .txnumevt = 1, > + .rxnumevt = 1, > +}; > +/* > + * The following EDMA channels/slots are not being used by drivers (for > + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence > + * they are being reserved for codecs on the DSP side. > + */ > +static const s16 da850_dma0_rsv_chans[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma0_rsv_slots[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 50}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_chans[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_slots[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 90}, > + {-1, -1} > +}; > + > +static struct edma_rsv_info da850_edma_cc0_rsv = { > + .rsv_chans = da850_dma0_rsv_chans, > + .rsv_slots = da850_dma0_rsv_slots, > +}; > + > +static struct edma_rsv_info da850_edma_cc1_rsv = { > + .rsv_chans = da850_dma1_rsv_chans, > + .rsv_slots = da850_dma1_rsv_slots, > +}; > + > +static struct edma_rsv_info *da850_edma_rsv[2] = { > + &da850_edma_cc0_rsv, > + &da850_edma_cc1_rsv, > +}; > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; > @@ -79,6 +161,29 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + > + ret = da850_register_edma(da850_edma_rsv); > + if (ret) > + pr_warning("hawk_init: edma registration failed: %d\n", > + ret); > + > + i2c_register_board_info(1, omapl138_hawk_i2c_devices, > + ARRAY_SIZE(omapl138_hawk_i2c_devices)); > + > + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "i2c0 registration failed: %d\n", > + ret); > + > + ret = davinci_cfg_reg_list(da850_mcasp_pins); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "mcasp mux setup failed: %d\n", > + ret); > + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); > + > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 63916b9..f033a0a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { > const short da850_mcasp_pins[] __initdata = { > DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, > DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, > - DA850_AXR_11, DA850_AXR_12, > + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, > -1 Is this change necessary? Regards, Caglar > }; > > diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig > index 6bbf001..cd29c81 100644 > --- a/sound/soc/davinci/Kconfig > +++ b/sound/soc/davinci/Kconfig > @@ -76,8 +76,8 @@ config SND_DA830_SOC_EVM > DA830/OMAP-L137 EVM > > config SND_DA850_SOC_EVM > - tristate "SoC Audio support for DA850/OMAP-L138 EVM" > - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM > + tristate "SoC Audio support for DA850/OMAP-L138 EVM / Hawkboard" > + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || > MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP > select SND_SOC_TLV320AIC3X > help > diff --git a/sound/soc/davinci/davinci-evm.c > b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 > --- a/sound/soc/davinci/davinci-evm.c > +++ b/sound/soc/davinci/davinci-evm.c > @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream > *substream, sysclk = 12288000; > > else if (machine_is_davinci_da830_evm() || > - machine_is_davinci_da850_evm()) > + machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) > sysclk = 24576000; > > else > @@ -311,7 +312,8 @@ static int __init evm_init(void) > } else if (machine_is_davinci_da830_evm()) { > evm_snd_dev_data = &da830_evm_snd_devdata; > index = 1; > - } else if (machine_is_davinci_da850_evm()) { > + } else if (machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) { > evm_snd_dev_data = &da850_evm_snd_devdata; > index = 0; > } else > From vm.rod25 at gmail.com Fri Oct 1 10:21:24 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Fri, 1 Oct 2010 10:21:24 -0500 Subject: [[RFC]PATCH v1] davinci: VGA support for Omapl138-Hawkboard In-Reply-To: <201010011457.22959.caglarakyuz@gmail.com> References: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> <4CA5BFFB.8060608@mvista.com> <201010011457.22959.caglarakyuz@gmail.com> Message-ID: On Fri, Oct 1, 2010 at 6:57 AM, Caglar Akyuz wrote: > On Friday 01 October 2010 02:03:23 pm Sergei Shtylyov wrote: >> Hello. >> >> On 01-10-2010 5:15, vm.rod25 at gmail.com wrote: >> > From: Victor Rodriguez >> > >> > This patch adds VGA support for the Hawkboard-L138 system >> > It is under the machine name "omapl138_hawkboard". >> > This system is based on the da850 davinci CPU architecture. >> > >> > Signed-off-by: Victor Rodriguez >> >> [...] >> >> > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> > b/arch/arm/mach-davinci/board-omapl138-hawk.c index d752244..ff009ad >> > 100644 >> > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> > @@ -183,6 +183,11 @@ static __init void omapl138_hawk_init(void) >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ret); >> > ? ? da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >> > >> > + ? ret = da8xx_register_lcdc(&vga_monitor_pdata); >> > + ? if (ret) >> > + ? ? ? ? ? pr_warning("omapl138_hawk_init: " >> > + ? ? ? ? ? ? ? ? ? "lcdc registration failed: %d\n", >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ret); >> >> ? ? Please align the above two lines. I suspect that could fit on one line >> ?too. >> >> > diff --git a/arch/arm/mach-davinci/devices-da8xx.c >> > b/arch/arm/mach-davinci/devices-da8xx.c index 9eec630..ad6fac2 100644 >> > --- a/arch/arm/mach-davinci/devices-da8xx.c >> > +++ b/arch/arm/mach-davinci/devices-da8xx.c >> > @@ -528,6 +528,12 @@ struct da8xx_lcdc_platform_data >> > sharp_lk043t1dg01_pdata = { .type ? ? ? ? ? ? ? ? ? = "Sharp_LK043T1DG01", >> > ? }; >> > >> > +struct da8xx_lcdc_platform_data vga_monitor_pdata = { >> > + ? .manu_name ? ? ? ? ? ? ?= "vga_mon", >> > + ? .controller_data ? ? ? ?= &lcd_cfg, >> > + ? .type ? ? ? ? ? ? ? ? ? = "VGA_Monitor", >> > +}; >> > + >> >> ? ? Sigh, this is a bad place for the platform data -- the platform data >> belongs to the board files. > > Indeed. Unfortunately lcd_cfg is statically defined in this file, I guess > that's why this is here at the moment. What I can do is to move static const struct display_panel disp_panel = { QVGA, 16, 16, COLOR_ACTIVE, }; static struct lcd_ctrl_config lcd_cfg = { &disp_panel, .ac_bias = 255, .ac_bias_intrpt = 0, .dma_burst_sz = 16, .bpp = 16, .fdd = 255, .tft_alt_mode = 0, .stn_565_mode = 0, .mono_8bit_mode = 0, .invert_line_clock = 1, .invert_frm_clock = 1, .sync_edge = 0, .sync_ctrl = 1, .raster_order = 0, }; struct da8xx_lcdc_platform_data vga_monitor_pdata = { .manu_name = "vga_mon", .controller_data = &lcd_cfg, .type = "VGA_Monitor", }; To the board file and it works, What do you think about it > Actually I prepared a patch to register display panels with fb driver, I would > prefer if this does not goes in as is. Otherwise, we need to patch kernel for > every panel/resolution combination users might have. Please send it, in order to test it, I have checked your patches on your gitorius repositories but seem that they are on other -rc and does not apply to the actual kernel version. Besides I found these discussion from Khasim previous patch https://patchwork.kernel.org/patch/62206/ and said that apply for all the other VGA monitors Please send your comments Sincerely yours Victor Rodriguez > Regards, > Caglar > >> >> [...] >> >> > diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c >> > index cad7d45..eea7264 100644 >> > --- a/drivers/video/da8xx-fb.c >> > +++ b/drivers/video/da8xx-fb.c >> > @@ -212,6 +212,21 @@ static struct da8xx_panel known_lcd_panels[] = { >> > ? ? ? ? ? ? .pxl_clk = 7833600, >> > ? ? ? ? ? ? .invert_pxl_clk = 0, >> > ? ? }, >> > + >> > + ? /* CRT Monitor or LCD Screen */ >> > + ? [2] = { >> > + ? ? ? ? ? .name = "VGA_Monitor", >> > + ? ? ? ? ? .width = 640, >> > + ? ? ? ? ? .height = 480, >> > + ? ? ? ? ? .hfp = 48, >> > + ? ? ? ? ? .hbp = 48, >> > + ? ? ? ? ? .hsw = 63, >> > + ? ? ? ? ? .vfp = 11, >> > + ? ? ? ? ? .vbp = 31, >> > + ? ? ? ? ? .vsw = 1, >> > + ? ? ? ? ? .pxl_clk = 25000000, >> > + ? ? ? ? ? .invert_pxl_clk = 1, >> > + ? }, >> > ? }; >> > >> > ? /* Enable the Raster Engine of the LCD Controller */ >> >> ? ? The drivers/video/ part should be in a separate patch. >> >> WBR, Sergei >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source >> > From sshtylyov at mvista.com Fri Oct 1 12:10:47 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 01 Oct 2010 21:10:47 +0400 Subject: [[RFC]PATCH v1] davinci: VGA support for Omapl138-Hawkboard In-Reply-To: References: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> <4CA5BFFB.8060608@mvista.com> <201010011457.22959.caglarakyuz@gmail.com> Message-ID: <4CA61617.6000905@mvista.com> Victor Rodriguez wrote: >>>> From: Victor Rodriguez >>>> This patch adds VGA support for the Hawkboard-L138 system >>>> It is under the machine name "omapl138_hawkboard". >>>> This system is based on the da850 davinci CPU architecture. >>>> Signed-off-by: Victor Rodriguez >>> [...] >>>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> b/arch/arm/mach-davinci/board-omapl138-hawk.c index d752244..ff009ad >>>> 100644 >>>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> @@ -183,6 +183,11 @@ static __init void omapl138_hawk_init(void) >>>> ret); >>>> da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >>>> >>>> + ret = da8xx_register_lcdc(&vga_monitor_pdata); >>>> + if (ret) >>>> + pr_warning("omapl138_hawk_init: " >>>> + "lcdc registration failed: %d\n", >>>> + ret); >>> Please align the above two lines. I suspect that could fit on one line >>> too. >>>> diff --git a/arch/arm/mach-davinci/devices-da8xx.c >>>> b/arch/arm/mach-davinci/devices-da8xx.c index 9eec630..ad6fac2 100644 >>>> --- a/arch/arm/mach-davinci/devices-da8xx.c >>>> +++ b/arch/arm/mach-davinci/devices-da8xx.c >>>> @@ -528,6 +528,12 @@ struct da8xx_lcdc_platform_data >>>> sharp_lk043t1dg01_pdata = { .type = "Sharp_LK043T1DG01", >>>> }; >>>> >>>> +struct da8xx_lcdc_platform_data vga_monitor_pdata = { >>>> + .manu_name = "vga_mon", >>>> + .controller_data = &lcd_cfg, >>>> + .type = "VGA_Monitor", >>>> +}; >>>> + >>> Sigh, this is a bad place for the platform data -- the platform data >>> belongs to the board files. >> Indeed. Unfortunately lcd_cfg is statically defined in this file, I guess >> that's why this is here at the moment. > What I can do is to move > static const struct display_panel disp_panel = { > QVGA, > 16, > 16, > COLOR_ACTIVE, > }; > static struct lcd_ctrl_config lcd_cfg = { > &disp_panel, > .ac_bias = 255, > .ac_bias_intrpt = 0, > .dma_burst_sz = 16, > .bpp = 16, > .fdd = 255, > .tft_alt_mode = 0, > .stn_565_mode = 0, > .mono_8bit_mode = 0, > .invert_line_clock = 1, > .invert_frm_clock = 1, > .sync_edge = 0, > .sync_ctrl = 1, > .raster_order = 0, > }; > > struct da8xx_lcdc_platform_data vga_monitor_pdata = { > .manu_name = "vga_mon", > .controller_data = &lcd_cfg, > .type = "VGA_Monitor", > }; > To the board file and it works, What do you think about it Just moving for Hawkboard it will break the other boards... WBR, Sergei From vm.rod25 at gmail.com Fri Oct 1 12:30:50 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Fri, 1 Oct 2010 12:30:50 -0500 Subject: [[RFC]PATCH v1] davinci: VGA support for Omapl138-Hawkboard In-Reply-To: <4CA61617.6000905@mvista.com> References: <1285895755-29129-1-git-send-email-vm.rod25@gmail.com> <4CA5BFFB.8060608@mvista.com> <201010011457.22959.caglarakyuz@gmail.com> <4CA61617.6000905@mvista.com> Message-ID: On Fri, Oct 1, 2010 at 12:10 PM, Sergei Shtylyov wrote: > Victor Rodriguez wrote: > >>>>> From: Victor Rodriguez > >>>>> This patch adds VGA support for the Hawkboard-L138 system >>>>> It is under the machine name "omapl138_hawkboard". >>>>> This system is based on the da850 davinci CPU architecture. > >>>>> Signed-off-by: Victor Rodriguez >>>> >>>> [...] > >>>>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>>> b/arch/arm/mach-davinci/board-omapl138-hawk.c index d752244..ff009ad >>>>> 100644 >>>>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>>>> @@ -183,6 +183,11 @@ static __init void omapl138_hawk_init(void) >>>>> ? ? ? ? ? ? ? ? ? ? ? ? ? ?ret); >>>>> ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >>>>> >>>>> + ? ret = da8xx_register_lcdc(&vga_monitor_pdata); >>>>> + ? if (ret) >>>>> + ? ? ? ? ? pr_warning("omapl138_hawk_init: " >>>>> + ? ? ? ? ? ? ? ? ? "lcdc registration failed: %d\n", >>>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ret); > >>>> ? ?Please align the above two lines. I suspect that could fit on one >>>> line >>>> ?too. > >>>>> diff --git a/arch/arm/mach-davinci/devices-da8xx.c >>>>> b/arch/arm/mach-davinci/devices-da8xx.c index 9eec630..ad6fac2 100644 >>>>> --- a/arch/arm/mach-davinci/devices-da8xx.c >>>>> +++ b/arch/arm/mach-davinci/devices-da8xx.c >>>>> @@ -528,6 +528,12 @@ struct da8xx_lcdc_platform_data >>>>> sharp_lk043t1dg01_pdata = { .type ? ? ? ? ? ? ? ? ? = >>>>> "Sharp_LK043T1DG01", >>>>> ?}; >>>>> >>>>> +struct da8xx_lcdc_platform_data vga_monitor_pdata = { >>>>> + ? .manu_name ? ? ? ? ? ? ?= "vga_mon", >>>>> + ? .controller_data ? ? ? ?= &lcd_cfg, >>>>> + ? .type ? ? ? ? ? ? ? ? ? = "VGA_Monitor", >>>>> +}; >>>>> + > >>>> ? ?Sigh, this is a bad place for the platform data -- the platform data >>>> belongs to the board files. > >>> Indeed. Unfortunately lcd_cfg is statically defined in this file, I guess >>> that's why this is here at the moment. > > >> What I can do is to move > > >> static const struct display_panel disp_panel = { >> ? ? ? ?QVGA, >> ? ? ? ?16, >> ? ? ? ?16, >> ? ? ? ?COLOR_ACTIVE, >> }; >> static struct lcd_ctrl_config lcd_cfg = { >> ? ? ? ?&disp_panel, >> ? ? ? ?.ac_bias ? ? ? ? ? ? ? ?= 255, >> ? ? ? ?.ac_bias_intrpt ? ? ? ? = 0, >> ? ? ? ?.dma_burst_sz ? ? ? ? ? = 16, >> ? ? ? ?.bpp ? ? ? ? ? ? ? ? ? ?= 16, >> ? ? ? ?.fdd ? ? ? ? ? ? ? ? ? ?= 255, >> ? ? ? ?.tft_alt_mode ? ? ? ? ? = 0, >> ? ? ? ?.stn_565_mode ? ? ? ? ? = 0, >> ? ? ? ?.mono_8bit_mode ? ? ? ? = 0, >> ? ? ? ?.invert_line_clock ? ? ?= 1, >> ? ? ? ?.invert_frm_clock ? ? ? = 1, >> ? ? ? ?.sync_edge ? ? ? ? ? ? ?= 0, >> ? ? ? ?.sync_ctrl ? ? ? ? ? ? ?= 1, >> ? ? ? ?.raster_order ? ? ? ? ? = 0, >> }; >> >> struct da8xx_lcdc_platform_data vga_monitor_pdata = { >> ? ? ? ?.manu_name ? ? ? ? ? ? ?= "vga_mon", >> ? ? ? ?.controller_data ? ? ? ?= &lcd_cfg, >> ? ? ? ?.type ? ? ? ? ? ? ? ? ? = "VGA_Monitor", >> }; > >> To the board file and it works, What do you think about it > > ? Just moving for Hawkboard it will break the other boards... > > WBR, Sergei > What do you think about the drivers/video part diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index cad7d45..eea7264 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -212,6 +212,21 @@ static struct da8xx_panel known_lcd_panels[] = { .pxl_clk = 7833600, .invert_pxl_clk = 0, }, + + /* CRT Monitor or LCD Screen */ + [2] = { + .name = "VGA_Monitor", + .width = 640, + .height = 480, + .hfp = 48, + .hbp = 48, + .hsw = 63, + .vfp = 11, + .vbp = 31, + .vsw = 1, + .pxl_clk = 25000000, + .invert_pxl_clk = 1, + }, }; Regards Victor Rodriguez From khilman at deeprootsystems.com Fri Oct 1 16:29:24 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:24 -0700 Subject: [PATCH 00/47] davinci queue for 2.6.37 Message-ID: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Here is the queue of davinci related changes that are currently staged in linux-next and will be submitted for 2.6.37. Note that the drivers/[input,net,mtd] changes all have acks/signoffs from those maintainers, but they are merging through the davinci tree along with platform related changes. Kevin Cyril Chemparathy (17): Davinci: tnetv107x: retain psc reg base after init davinci: add idcode for tnetv107x rev 1.1/1.2 net: davinci_emac: separate out davinci mdio davinci: add mdio platform devices omap: add mdio platform devices net: davinci_emac: switch to new mdio davinci: cleanup mdio arch code and switch to phy_id omap: cleanup unused davinci mdio arch code net: davinci_emac: cleanup unused mdio emac code net: davinci_emac: separate out cpdma code net: davinci_emac: switch to new cpdma layer net: davinci_emac: cleanup unused cpdma code input: add driver for tnetv107x on-chip keypad controller davinci: add tnetv107x keypad platform device davinci: add keypad config for tnetv107x evm board input: add driver for tnetv107x touchscreen controller davinci: add tnetv107x touchscreen platform device Juha Kuikka (3): DA850: Add LPSC id for MMCSD1 peripheral DA850: Split MMCSD clock into two to support both MMCSD peripherals DA850: Add MMCSD1 resources, platform device and convenience registration function Kevin Hilman (1): davinci: clock: make 'disable unused clocks' printk debug only Kulikov Vasiliy (1): arm: mach-davinci: check irq2ctlr() result Michael Williamson (5): davinci: Add machine checks to DA8XX serial console init routines davinci: Add CONFIG_REGULATOR_DUMMY to DA8XX defconfig file. davinci: Initial support for MityDSP-L138/MityARM-1808 davinci: Add I2C0 devices to MityDSP-L138/MityARM-1808 platform davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom Sekhar Nori (16): davinci: da850 evm: sparse cleanup: make file local variables static MAINTAINERS: Add Kevin's e-mail in entry for TI DaVinci davinci: cpufreq: bailout on regulator errors davinci: clean up inconsistent usage of spaces in Kconfig davinci: introduce support for AM1x ARM9 microprocessors davinci: am18x/da850/omap-l138: use 'NOM' voltage defined in datasheet as min voltage davinci: dm365: disable pulldowns for all MMC/SD1 pins. davinci: clock: add support for setting sysclk rate davinci: cpufreq: add support for keeping an additional clock constant davinci: am18x/da850/omap-l138: keep async clock constant with cpufreq davinci: dm365 evm: use EDMAQ_3 as the audio DMA queue davinci: add support for aemif timing configuration nand: davinci: add support for timing configuration davinci: dm644x evm: setup NAND flash timing davinci: am18x/da850/omap-l138 evm: setup NAND flash timing davinci: dm6467t evm: setup NAND flash timing Sergei Shtylyov (2): DA850: move NAND/NOR pin lists to the board file DA850: move MII/RMII pin lists to the board file Sudhakar Rajashekhara (1): davinci: am17x/da830/omap-l137 evm: setup NAND flash timing Victor Rodriguez (1): davinci: Initial support for Omapl138-Hawkboard MAINTAINERS | 4 +- arch/arm/configs/da8xx_omapl_defconfig | 3 + arch/arm/mach-davinci/Kconfig | 76 +- arch/arm/mach-davinci/Makefile | 4 +- arch/arm/mach-davinci/aemif.c | 133 +++ arch/arm/mach-davinci/board-da830-evm.c | 24 +- arch/arm/mach-davinci/board-da850-evm.c | 91 ++- arch/arm/mach-davinci/board-dm365-evm.c | 11 +- arch/arm/mach-davinci/board-dm644x-evm.c | 20 +- arch/arm/mach-davinci/board-dm646x-evm.c | 21 +- arch/arm/mach-davinci/board-mityomapl138.c | 424 +++++++ arch/arm/mach-davinci/board-neuros-osd2.c | 7 +- arch/arm/mach-davinci/board-omapl138-hawk.c | 64 ++ arch/arm/mach-davinci/board-sffsdr.c | 7 +- arch/arm/mach-davinci/board-tnetv107x-evm.c | 56 + arch/arm/mach-davinci/clock.c | 75 ++- arch/arm/mach-davinci/clock.h | 5 + arch/arm/mach-davinci/cpufreq.c | 28 +- arch/arm/mach-davinci/da850.c | 76 +- arch/arm/mach-davinci/devices-da8xx.c | 70 ++- arch/arm/mach-davinci/devices-tnetv107x.c | 50 + arch/arm/mach-davinci/devices.c | 2 +- arch/arm/mach-davinci/dm365.c | 23 +- arch/arm/mach-davinci/dm644x.c | 23 +- arch/arm/mach-davinci/dm646x.c | 22 +- arch/arm/mach-davinci/dma.c | 8 +- arch/arm/mach-davinci/include/mach/aemif.h | 36 + arch/arm/mach-davinci/include/mach/da8xx.h | 7 +- arch/arm/mach-davinci/include/mach/dm365.h | 2 +- arch/arm/mach-davinci/include/mach/dm644x.h | 2 +- arch/arm/mach-davinci/include/mach/dm646x.h | 2 +- arch/arm/mach-davinci/include/mach/nand.h | 6 +- arch/arm/mach-davinci/include/mach/psc.h | 1 + arch/arm/mach-davinci/include/mach/tnetv107x.h | 3 + arch/arm/mach-davinci/include/mach/uncompress.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 11 +- arch/arm/mach-omap2/board-am3517evm.c | 31 +- drivers/input/keyboard/Kconfig | 9 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/tnetv107x-keypad.c | 340 ++++++ drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tnetv107x-ts.c | 396 +++++++ drivers/mtd/nand/davinci_nand.c | 61 +- drivers/net/Kconfig | 21 + drivers/net/Makefile | 2 + drivers/net/davinci_cpdma.c | 965 ++++++++++++++++ drivers/net/davinci_cpdma.h | 108 ++ drivers/net/davinci_emac.c | 1338 +++-------------------- drivers/net/davinci_mdio.c | 475 ++++++++ include/linux/davinci_emac.h | 16 +- 51 files changed, 3814 insertions(+), 1358 deletions(-) create mode 100644 arch/arm/mach-davinci/aemif.c create mode 100644 arch/arm/mach-davinci/board-mityomapl138.c create mode 100644 arch/arm/mach-davinci/board-omapl138-hawk.c create mode 100644 arch/arm/mach-davinci/include/mach/aemif.h create mode 100644 drivers/input/keyboard/tnetv107x-keypad.c create mode 100644 drivers/input/touchscreen/tnetv107x-ts.c create mode 100644 drivers/net/davinci_cpdma.c create mode 100644 drivers/net/davinci_cpdma.h create mode 100644 drivers/net/davinci_mdio.c -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:25 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:25 -0700 Subject: [PATCH 01/47] davinci: da850 evm: sparse cleanup: make file local variables static In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-2-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Without this cleanup, sparse checker reports warnings of the type: CHECK arch/arm/mach-davinci/board-da850-evm.c arch/arm/mach-davinci/board-da850-evm.c:112:22: warning: symbol 'da850_evm_nandflash_partition' was not declared. Should it be static? The nand flash partitions and regulator supplies are used within the EVM file and so should have been static This patch has been boot tested on DA830 and DA850 EVMs. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index fdc2cc5..711a56a 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -110,7 +110,7 @@ static struct platform_device da850_pm_device = { * to boot, using TI's tools to install the secondary boot loader * (UBL) and U-Boot. */ -struct mtd_partition da850_evm_nandflash_partition[] = { +static struct mtd_partition da850_evm_nandflash_partition[] = { { .name = "u-boot env", .offset = 0, @@ -406,7 +406,7 @@ static int da850_lcd_hw_init(void) /* TPS65070 voltage regulator support */ /* 3.3V */ -struct regulator_consumer_supply tps65070_dcdc1_consumers[] = { +static struct regulator_consumer_supply tps65070_dcdc1_consumers[] = { { .supply = "usb0_vdda33", }, @@ -416,7 +416,7 @@ struct regulator_consumer_supply tps65070_dcdc1_consumers[] = { }; /* 3.3V or 1.8V */ -struct regulator_consumer_supply tps65070_dcdc2_consumers[] = { +static struct regulator_consumer_supply tps65070_dcdc2_consumers[] = { { .supply = "dvdd3318_a", }, @@ -429,14 +429,14 @@ struct regulator_consumer_supply tps65070_dcdc2_consumers[] = { }; /* 1.2V */ -struct regulator_consumer_supply tps65070_dcdc3_consumers[] = { +static struct regulator_consumer_supply tps65070_dcdc3_consumers[] = { { .supply = "cvdd", }, }; /* 1.8V LDO */ -struct regulator_consumer_supply tps65070_ldo1_consumers[] = { +static struct regulator_consumer_supply tps65070_ldo1_consumers[] = { { .supply = "sata_vddr", }, @@ -452,7 +452,7 @@ struct regulator_consumer_supply tps65070_ldo1_consumers[] = { }; /* 1.2V LDO */ -struct regulator_consumer_supply tps65070_ldo2_consumers[] = { +static struct regulator_consumer_supply tps65070_ldo2_consumers[] = { { .supply = "sata_vdd", }, @@ -475,7 +475,7 @@ static struct tps6507x_reg_platform_data tps6507x_platform_data = { .defdcdc_default = true, }; -struct regulator_init_data tps65070_regulator_data[] = { +static struct regulator_init_data tps65070_regulator_data[] = { /* dcdc1 */ { .constraints = { -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:26 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:26 -0700 Subject: [PATCH 02/47] MAINTAINERS: Add Kevin's e-mail in entry for TI DaVinci In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-3-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori In absence of Kevin's e-mail address, using get_maintaner.pl in git-send-email --cc-cmd option is not CCing Kevin at all. While at it, mark davinci-linux-open-source at linux.davincidsp.com as a list in line with what is being done for other maintainer entries. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- MAINTAINERS | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 50b8148..35612dd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5247,8 +5247,8 @@ F: drivers/*/*s3c2410* F: drivers/*/*/*s3c2410* TI DAVINCI MACHINE SUPPORT -P: Kevin Hilman -M: davinci-linux-open-source at linux.davincidsp.com +M: Kevin Hilman +L: davinci-linux-open-source at linux.davincidsp.com (subscribers-only) Q: http://patchwork.kernel.org/project/linux-davinci/list/ S: Supported F: arch/arm/mach-davinci -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:27 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:27 -0700 Subject: [PATCH 03/47] davinci: clock: make 'disable unused clocks' printk debug only In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-4-git-send-email-khilman@deeprootsystems.com> The long list of clocks being disabled on boot is noisy and not needed for standard boots. Make this a debug printk instead. Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 054c303..5b0cb62 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -236,7 +236,7 @@ static int __init clk_disable_unused(void) if (!davinci_psc_is_clk_active(ck->gpsc, ck->lpsc)) continue; - pr_info("Clocks: disable unused %s\n", ck->name); + pr_debug("Clocks: disable unused %s\n", ck->name); davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, (ck->flags & PSC_SWRSTDISABLE) ? -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:28 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:28 -0700 Subject: [PATCH 04/47] davinci: cpufreq: bailout on regulator errors In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-5-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Current cpufreq code does not consider errors that can occur while changing voltage. Code to increase CPU frequency goes ahead even in the case the regulator has failed to increase the voltage. This leads to hard error since lower voltages cannot support increased frequency. Prevent this by not increasing frequency in case increasing voltage is not successful. Also, do not lower the voltage if changing the cpu frequency has failed for some reason. Note that we do not return error on failure to decrease voltage as that is not a hard error. Build fix for non-cpufreq kernels by Caglar Akyuz. Signed-off-by: Sekhar Nori Cc: Caglar Akyuz Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/cpufreq.c | 10 ++++++++-- arch/arm/mach-davinci/da850.c | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index d3fa6de..bc80142 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c @@ -104,15 +104,21 @@ static int davinci_target(struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); /* if moving to higher frequency, up the voltage beforehand */ - if (pdata->set_voltage && freqs.new > freqs.old) - pdata->set_voltage(idx); + if (pdata->set_voltage && freqs.new > freqs.old) { + ret = pdata->set_voltage(idx); + if (ret) + goto out; + } ret = clk_set_rate(armclk, idx); + if (ret) + goto out; /* if moving to lower freq, lower the voltage after lowering freq */ if (pdata->set_voltage && freqs.new < freqs.old) pdata->set_voltage(idx); +out: cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); return ret; diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 68ed58a..868227e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -983,7 +983,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index) return 0; } #else -int __init da850_register_cpufreq(void) +int __init da850_register_cpufreq(char *async_clk) { return 0; } -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:29 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:29 -0700 Subject: [PATCH 05/47] davinci: clean up inconsistent usage of spaces in Kconfig In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-6-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori In arch/arm/mach-davinci/Kconfig, some of the configuration items are indented with multiple spaces instead of tabs. Also, in couple of places, two spaces are used in the middle of help text where one should do. This patch fixes both issues. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 32 ++++++++++++++++---------------- 1 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 71f90f8..b291da1 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -20,17 +20,17 @@ config ARCH_DAVINCI_DM644x select ARCH_DAVINCI_DMx config ARCH_DAVINCI_DM355 - bool "DaVinci 355 based system" + bool "DaVinci 355 based system" select AINTC select ARCH_DAVINCI_DMx config ARCH_DAVINCI_DM646x - bool "DaVinci 646x based system" + bool "DaVinci 646x based system" select AINTC select ARCH_DAVINCI_DMx config ARCH_DAVINCI_DA830 - bool "DA830/OMAP-L137 based system" + bool "DA830/OMAP-L137 based system" select CP_INTC select ARCH_DAVINCI_DA8XX select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1 @@ -140,7 +140,7 @@ config DA830_UI_LCD config DA830_UI_NAND bool "NAND flash" help - Say Y here to use the NAND flash. Do not forget to setup + Say Y here to use the NAND flash. Do not forget to setup the switch correctly. endchoice @@ -195,20 +195,20 @@ config DAVINCI_MUX say Y. config DAVINCI_MUX_DEBUG - bool "Multiplexing debug output" - depends on DAVINCI_MUX - help - Makes the multiplexing functions print out a lot of debug info. - This is useful if you want to find out the correct values of the - multiplexing registers. + bool "Multiplexing debug output" + depends on DAVINCI_MUX + help + Makes the multiplexing functions print out a lot of debug info. + This is useful if you want to find out the correct values of the + multiplexing registers. config DAVINCI_MUX_WARNINGS - bool "Warn about pins the bootloader didn't set up" - depends on DAVINCI_MUX - help - Choose Y here to warn whenever driver initialization logic needs - to change the pin multiplexing setup. When there are no warnings - printed, it's safe to deselect DAVINCI_MUX for your product. + bool "Warn about pins the bootloader didn't set up" + depends on DAVINCI_MUX + help + Choose Y here to warn whenever driver initialization logic needs + to change the pin multiplexing setup. When there are no warnings + printed, it's safe to deselect DAVINCI_MUX for your product. config DAVINCI_RESET_CLOCKS bool "Reset unused clocks during boot" -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:30 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:30 -0700 Subject: [PATCH 06/47] davinci: introduce support for AM1x ARM9 microprocessors In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-7-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori The Sitara AM17x SoCs from TI are an OMAP-L137 pin-to-pin compatible ARM9 microprocessor offering from TI. The Sitara AM18x SoCs from TI are an OMAP-L138 pin-to-pin compatible ARM9 microprocessor offering from TI. More information about these processors available at: www.ti.com/am1x Because of their compatibiliy with OMAP-L1x, the kernel support for OMAP-L1x is fully relevant to AM1x processors. This patch updates the Kconfig prompt and help text to include the AM1x part names to help users select configurations required for these parts easily. Also, the hardware information that shows up in /proc/cpuinfo is updated to show applicability of the respective OMAP-L1x EVMs for AM1x parts. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Kconfig | 30 +++++++++++++++--------------- arch/arm/mach-davinci/board-da830-evm.c | 2 +- arch/arm/mach-davinci/board-da850-evm.c | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index b291da1..2bf03e9 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -30,13 +30,13 @@ config ARCH_DAVINCI_DM646x select ARCH_DAVINCI_DMx config ARCH_DAVINCI_DA830 - bool "DA830/OMAP-L137 based system" + bool "DA830/OMAP-L137/AM17x based system" select CP_INTC select ARCH_DAVINCI_DA8XX select CPU_DCACHE_WRITETHROUGH # needed on silicon revs 1.0, 1.1 config ARCH_DAVINCI_DA850 - bool "DA850/OMAP-L138 based system" + bool "DA850/OMAP-L138/AM18x based system" select CP_INTC select ARCH_DAVINCI_DA8XX select ARCH_HAS_CPUFREQ @@ -115,21 +115,21 @@ config MACH_DAVINCI_DM365_EVM for development is a DM365 EVM config MACH_DAVINCI_DA830_EVM - bool "TI DA830/OMAP-L137 Reference Platform" + bool "TI DA830/OMAP-L137/AM17x Reference Platform" default ARCH_DAVINCI_DA830 depends on ARCH_DAVINCI_DA830 select GPIO_PCF857X help - Say Y here to select the TI DA830/OMAP-L137 Evaluation Module. + Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. choice - prompt "Select DA830/OMAP-L137 UI board peripheral" + prompt "Select DA830/OMAP-L137/AM17x UI board peripheral" depends on MACH_DAVINCI_DA830_EVM help - The presence of UI card on the DA830/OMAP-L137 EVM is detected - automatically based on successful probe of the I2C based GPIO - expander on that board. This option selected in this menu has - an effect only in case of a successful UI card detection. + The presence of UI card on the DA830/OMAP-L137/AM17x EVM is + detected automatically based on successful probe of the I2C + based GPIO expander on that board. This option selected in this + menu has an effect only in case of a successful UI card detection. config DA830_UI_LCD bool "LCD" @@ -145,18 +145,18 @@ config DA830_UI_NAND endchoice config MACH_DAVINCI_DA850_EVM - bool "TI DA850/OMAP-L138 Reference Platform" + bool "TI DA850/OMAP-L138/AM18x Reference Platform" default ARCH_DAVINCI_DA850 depends on ARCH_DAVINCI_DA850 select GPIO_PCA953X help - Say Y here to select the TI DA850/OMAP-L138 Evaluation Module. + Say Y here to select the TI DA850/OMAP-L138/AM18x Evaluation Module. choice prompt "Select peripherals connected to expander on UI board" depends on MACH_DAVINCI_DA850_EVM help - The presence of User Interface (UI) card on the DA850/OMAP-L138 + The presence of User Interface (UI) card on the DA850/OMAP-L138/AM18x EVM is detected automatically based on successful probe of the I2C based GPIO expander on that card. This option selected in this menu has an effect only in case of a successful UI card detection. @@ -165,13 +165,13 @@ config DA850_UI_NONE bool "No peripheral is enabled" help Say Y if you do not want to enable any of the peripherals connected - to TCA6416 expander on DA850/OMAP-L138 EVM UI card + to TCA6416 expander on DA850/OMAP-L138/AM18x EVM UI card config DA850_UI_RMII bool "RMII Ethernet PHY" help - Say Y if you want to use the RMII PHY on the DA850/OMAP-L138 EVM. - This PHY is found on the UI daughter card that is supplied with + Say Y if you want to use the RMII PHY on the DA850/OMAP-L138/AM18x + EVM. This PHY is found on the UI daughter card that is supplied with the EVM. NOTE: Please take care while choosing this option, MII PHY will not be functional if RMII mode is selected. diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index c3994f3..292e8b7 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -596,7 +596,7 @@ static void __init da830_evm_map_io(void) da830_init(); } -MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137 EVM") +MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DA8XX_DDR_BASE + 0x100), diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 711a56a..f5f9472 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -816,7 +816,7 @@ static void __init da850_evm_map_io(void) da850_init(); } -MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138 EVM") +MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .phys_io = IO_PHYS, .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, .boot_params = (DA8XX_DDR_BASE + 0x100), -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:31 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:31 -0700 Subject: [PATCH 07/47] davinci: am18x/da850/omap-l138: use 'NOM' voltage defined in datasheet as min voltage In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-8-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori For each DA850 OPP, the normal ('NOM') voltage defined in the tecnical reference manual (TRM) is actually the minimum voltage the frequency is supported at. The minimum ('MIN') voltage defined in TRM is meant to take care of voltage fluctuations and the device should not be run at this voltage for extended periods of time. Fix the OPP definitions to define the cvdd_min as the normal voltage defined in the datasheet. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da850.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 868227e..6932d80 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -851,7 +851,7 @@ static const struct da850_opp da850_opp_300 = { .prediv = 1, .mult = 25, .postdiv = 2, - .cvdd_min = 1140000, + .cvdd_min = 1200000, .cvdd_max = 1320000, }; @@ -860,7 +860,7 @@ static const struct da850_opp da850_opp_200 = { .prediv = 1, .mult = 25, .postdiv = 3, - .cvdd_min = 1050000, + .cvdd_min = 1100000, .cvdd_max = 1160000, }; @@ -869,7 +869,7 @@ static const struct da850_opp da850_opp_96 = { .prediv = 1, .mult = 20, .postdiv = 5, - .cvdd_min = 950000, + .cvdd_min = 1000000, .cvdd_max = 1050000, }; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:32 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:32 -0700 Subject: [PATCH 08/47] davinci: dm365: disable pulldowns for all MMC/SD1 pins. In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-9-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori This patch disables internal pulldowns for all MMC/SD1 pins. Presently only MMCSD1_CMD pin's pull down is disabled, but with this some MMC/SD cards do not get detected on MMC/SD1 slot of the EVM. The problem was reproducible with SanDisk 4GB SDHC card. Reported-by: Stephane Bovagne Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 8b7201e..2a9a252 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -213,7 +213,7 @@ void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE + 0x7c); /* Configure pull down control */ - __raw_writel((__raw_readl(pupdctl1) & ~0x400), + __raw_writel((__raw_readl(pupdctl1) & ~0xfc0), pupdctl1); mmcsd1_resources[0].start = DM365_MMCSD1_BASE; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:33 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:33 -0700 Subject: [PATCH 09/47] davinci: clock: add support for setting sysclk rate In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-10-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Setting sysclk rate will be useful in cases where the sysclk is not at a fixed ratio to the PLL output but can asynchronously be changed. This support forms the basis of attempt to keep the AEMIF clock constant on OMAP-L138 even as PLL0 output changes as ARM clock is changed to save power. This patch has been tested on OMAP-L138. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/clock.c | 73 +++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-davinci/clock.h | 5 +++ 2 files changed, 78 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 5b0cb62..01ba080 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -287,6 +287,79 @@ static unsigned long clk_sysclk_recalc(struct clk *clk) return rate; } +int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) +{ + unsigned v; + struct pll_data *pll; + unsigned long input; + unsigned ratio = 0; + + /* If this is the PLL base clock, wrong function to call */ + if (clk->pll_data) + return -EINVAL; + + /* There must be a parent... */ + if (WARN_ON(!clk->parent)) + return -EINVAL; + + /* ... the parent must be a PLL... */ + if (WARN_ON(!clk->parent->pll_data)) + return -EINVAL; + + /* ... and this clock must have a divider. */ + if (WARN_ON(!clk->div_reg)) + return -EINVAL; + + pll = clk->parent->pll_data; + + input = clk->parent->rate; + + /* If pre-PLL, source clock is before the multiplier and divider(s) */ + if (clk->flags & PRE_PLL) + input = pll->input_rate; + + if (input > rate) { + /* + * Can afford to provide an output little higher than requested + * only if maximum rate supported by hardware on this sysclk + * is known. + */ + if (clk->maxrate) { + ratio = DIV_ROUND_CLOSEST(input, rate); + if (input / ratio > clk->maxrate) + ratio = 0; + } + + if (ratio == 0) + ratio = DIV_ROUND_UP(input, rate); + + ratio--; + } + + if (ratio > PLLDIV_RATIO_MASK) + return -EINVAL; + + do { + v = __raw_readl(pll->base + PLLSTAT); + } while (v & PLLSTAT_GOSTAT); + + v = __raw_readl(pll->base + clk->div_reg); + v &= ~PLLDIV_RATIO_MASK; + v |= ratio | PLLDIV_EN; + __raw_writel(v, pll->base + clk->div_reg); + + v = __raw_readl(pll->base + PLLCMD); + v |= PLLCMD_GOSET; + __raw_writel(v, pll->base + PLLCMD); + + do { + v = __raw_readl(pll->base + PLLSTAT); + } while (v & PLLSTAT_GOSTAT); + + return 0; +} +EXPORT_SYMBOL(davinci_set_sysclk_rate); + static unsigned long clk_leafclk_recalc(struct clk *clk) { if (WARN_ON(!clk->parent)) diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 01e3648..1109998 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -70,6 +70,9 @@ #include #include +#define PLLSTAT_GOSTAT BIT(0) +#define PLLCMD_GOSET BIT(0) + struct pll_data { u32 phys_base; void __iomem *base; @@ -86,6 +89,7 @@ struct clk { struct module *owner; const char *name; unsigned long rate; + unsigned long maxrate; /* H/W supported max rate */ u8 usecount; u8 lpsc; u8 gpsc; @@ -118,6 +122,7 @@ struct clk { int davinci_clk_init(struct clk_lookup *clocks); int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv, unsigned int mult, unsigned int postdiv); +int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate); extern struct platform_device davinci_wdt_device; extern void davinci_watchdog_reset(struct platform_device *); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:34 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:34 -0700 Subject: [PATCH 10/47] davinci: cpufreq: add support for keeping an additional clock constant In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-11-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori On OMAP-L138 SoC, some of the sysclks need not be at a fixed ratio to CPU clock and can be kept at a relatively constant rate by adjusting the PLLDIVn ratio even as cpufreq goes ahead and changes the CPU clock. This feature can be used to keep the EMIFA (PLL0 SYSCLK3) clock at a constant rate so that the EMIF timings need not be re-programmed whenever the CPU frequency changes. This patch adds the required suppport to cpufreq driver. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/cpufreq.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index bc80142..343de73 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c @@ -34,6 +34,8 @@ struct davinci_cpufreq { struct device *dev; struct clk *armclk; + struct clk *asyncclk; + unsigned long asyncrate; }; static struct davinci_cpufreq cpufreq; @@ -114,6 +116,12 @@ static int davinci_target(struct cpufreq_policy *policy, if (ret) goto out; + if (cpufreq.asyncclk) { + ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); + if (ret) + goto out; + } + /* if moving to lower freq, lower the voltage after lowering freq */ if (pdata->set_voltage && freqs.new < freqs.old) pdata->set_voltage(idx); @@ -191,6 +199,7 @@ static struct cpufreq_driver davinci_driver = { static int __init davinci_cpufreq_probe(struct platform_device *pdev) { struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; + struct clk *asyncclk; if (!pdata) return -EINVAL; @@ -205,6 +214,12 @@ static int __init davinci_cpufreq_probe(struct platform_device *pdev) return PTR_ERR(cpufreq.armclk); } + asyncclk = clk_get(cpufreq.dev, "async"); + if (!IS_ERR(asyncclk)) { + cpufreq.asyncclk = asyncclk; + cpufreq.asyncrate = clk_get_rate(asyncclk); + } + return cpufreq_register_driver(&davinci_driver); } @@ -212,6 +227,9 @@ static int __exit davinci_cpufreq_remove(struct platform_device *pdev) { clk_put(cpufreq.armclk); + if (cpufreq.asyncclk) + clk_put(cpufreq.asyncclk); + return cpufreq_unregister_driver(&davinci_driver); } -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:35 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:35 -0700 Subject: [PATCH 11/47] davinci: am18x/da850/omap-l138: keep async clock constant with cpufreq In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-12-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Keep PLL0 SYSCLK3 at a constant rate of 100MHz. This enables the AEMIF timing to remain valid even as the PLL0 output is changed by cpufreq driver to save power. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 2 +- arch/arm/mach-davinci/da850.c | 10 +++++++++- arch/arm/mach-davinci/include/mach/da8xx.h | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index f5f9472..c2800a98 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -787,7 +787,7 @@ static __init void da850_evm_init(void) if (ret) pr_warning("da850_evm_init: rtc setup failed: %d\n", ret); - ret = da850_register_cpufreq(); + ret = da850_register_cpufreq("pll0_sysclk3"); if (ret) pr_warning("da850_evm_init: cpufreq registration failed: %d\n", ret); diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 6932d80..5af7cfb 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -86,6 +86,8 @@ static struct clk pll0_sysclk3 = { .parent = &pll0_clk, .flags = CLK_PLL, .div_reg = PLLDIV3, + .set_rate = davinci_set_sysclk_rate, + .maxrate = 100000000, }; static struct clk pll0_sysclk4 = { @@ -929,10 +931,16 @@ static struct platform_device da850_cpufreq_device = { .dev = { .platform_data = &cpufreq_info, }, + .id = -1, }; -int __init da850_register_cpufreq(void) +int __init da850_register_cpufreq(char *async_clk) { + /* cpufreq driver can help keep an "async" clock constant */ + if (async_clk) + clk_add_alias("async", da850_cpufreq_device.name, + async_clk, NULL); + return platform_device_register(&da850_cpufreq_device); } diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 3c07059..2c3f418 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -78,7 +78,7 @@ int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata); int da8xx_register_mmcsd0(struct davinci_mmc_config *config); void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata); int da8xx_register_rtc(void); -int da850_register_cpufreq(void); +int da850_register_cpufreq(char *async_clk); int da8xx_register_cpuidle(void); void __iomem * __init da8xx_get_mem_ctlr(void); int da850_register_pm(struct platform_device *pdev); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:36 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:36 -0700 Subject: [PATCH 12/47] Davinci: tnetv107x: retain psc reg base after init In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-13-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This is a bugfix for the original tnetv107x submission series. The psc_regs base array was being discarded post-init, and this was causing a crash during post-init clock enable/disable. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/tnetv107x.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index 864e604..06d2ac9 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -104,7 +104,7 @@ static u32 pll_ext_freq[] = { }; /* PSC control registers */ -static u32 psc_regs[] __initconst = { TNETV107X_PSC_BASE }; +static u32 psc_regs[] = { TNETV107X_PSC_BASE }; /* Host map for interrupt controller */ static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 }; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:37 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:37 -0700 Subject: [PATCH 13/47] DA850: move NAND/NOR pin lists to the board file In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-14-git-send-email-khilman@deeprootsystems.com> From: Sergei Shtylyov The NAND/NOR flash pin lists (da850_nand_pins/da850_nor_pins) are purely board specific and as such shouldn't be in da850.c -- copy them to board-da850-evm.c, renaming to da850_evm_nand_pins/da850_evm_nor_pins respectively, and merge the two lists in da850.c into one, representing the EMIF 2.5 module as a whole, just like we have it in da830.c... While at it, remove the '__init' modifier from da850_evm_setup_nor_nand() as this function is called from non '__init' code... Signed-off-by: Sergei Shtylyov Tested-by: Ben Gardiner Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 30 +++++++++++++++++++++++-- arch/arm/mach-davinci/da850.c | 32 ++++++++++----------------- arch/arm/mach-davinci/include/mach/da8xx.h | 3 +- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index c2800a98..482d458 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -196,6 +196,30 @@ static void __init da850_evm_init_nor(void) iounmap(aemif_addr); } +static const short da850_evm_nand_pins[] = { + DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3, + DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7, + DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4, + DA850_NEMA_WE, DA850_NEMA_OE, + -1 +}; + +static const short da850_evm_nor_pins[] = { + DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2, + DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1, + DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5, + DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9, + DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13, + DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1, + DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5, + DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9, + DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13, + DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17, + DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21, + DA850_EMA_A_22, DA850_EMA_A_23, + -1 +}; + static u32 ui_card_detected; #if defined(CONFIG_MMC_DAVINCI) || \ @@ -205,17 +229,17 @@ static u32 ui_card_detected; #define HAS_MMC 0 #endif -static __init void da850_evm_setup_nor_nand(void) +static inline void da850_evm_setup_nor_nand(void) { int ret = 0; if (ui_card_detected & !HAS_MMC) { - ret = davinci_cfg_reg_list(da850_nand_pins); + ret = davinci_cfg_reg_list(da850_evm_nand_pins); if (ret) pr_warning("da850_evm_init: nand mux setup failed: " "%d\n", ret); - ret = davinci_cfg_reg_list(da850_nor_pins); + ret = davinci_cfg_reg_list(da850_evm_nor_pins); if (ret) pr_warning("da850_evm_init: nor mux setup failed: %d\n", ret); diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 5af7cfb..efb904e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -609,27 +609,19 @@ const short da850_mmcsd0_pins[] __initdata = { -1 }; -const short da850_nand_pins[] __initdata = { - DA850_EMA_D_7, DA850_EMA_D_6, DA850_EMA_D_5, DA850_EMA_D_4, - DA850_EMA_D_3, DA850_EMA_D_2, DA850_EMA_D_1, DA850_EMA_D_0, - DA850_EMA_A_1, DA850_EMA_A_2, DA850_NEMA_CS_3, DA850_NEMA_CS_4, - DA850_NEMA_WE, DA850_NEMA_OE, - -1 -}; - -const short da850_nor_pins[] __initdata = { +const short da850_emif25_pins[] __initdata = { DA850_EMA_BA_1, DA850_EMA_CLK, DA850_EMA_WAIT_1, DA850_NEMA_CS_2, - DA850_NEMA_WE, DA850_NEMA_OE, DA850_EMA_D_0, DA850_EMA_D_1, - DA850_EMA_D_2, DA850_EMA_D_3, DA850_EMA_D_4, DA850_EMA_D_5, - DA850_EMA_D_6, DA850_EMA_D_7, DA850_EMA_D_8, DA850_EMA_D_9, - DA850_EMA_D_10, DA850_EMA_D_11, DA850_EMA_D_12, DA850_EMA_D_13, - DA850_EMA_D_14, DA850_EMA_D_15, DA850_EMA_A_0, DA850_EMA_A_1, - DA850_EMA_A_2, DA850_EMA_A_3, DA850_EMA_A_4, DA850_EMA_A_5, - DA850_EMA_A_6, DA850_EMA_A_7, DA850_EMA_A_8, DA850_EMA_A_9, - DA850_EMA_A_10, DA850_EMA_A_11, DA850_EMA_A_12, DA850_EMA_A_13, - DA850_EMA_A_14, DA850_EMA_A_15, DA850_EMA_A_16, DA850_EMA_A_17, - DA850_EMA_A_18, DA850_EMA_A_19, DA850_EMA_A_20, DA850_EMA_A_21, - DA850_EMA_A_22, DA850_EMA_A_23, + DA850_NEMA_CS_3, DA850_NEMA_CS_4, DA850_NEMA_WE, DA850_NEMA_OE, + DA850_EMA_D_0, DA850_EMA_D_1, DA850_EMA_D_2, DA850_EMA_D_3, + DA850_EMA_D_4, DA850_EMA_D_5, DA850_EMA_D_6, DA850_EMA_D_7, + DA850_EMA_D_8, DA850_EMA_D_9, DA850_EMA_D_10, DA850_EMA_D_11, + DA850_EMA_D_12, DA850_EMA_D_13, DA850_EMA_D_14, DA850_EMA_D_15, + DA850_EMA_A_0, DA850_EMA_A_1, DA850_EMA_A_2, DA850_EMA_A_3, + DA850_EMA_A_4, DA850_EMA_A_5, DA850_EMA_A_6, DA850_EMA_A_7, + DA850_EMA_A_8, DA850_EMA_A_9, DA850_EMA_A_10, DA850_EMA_A_11, + DA850_EMA_A_12, DA850_EMA_A_13, DA850_EMA_A_14, DA850_EMA_A_15, + DA850_EMA_A_16, DA850_EMA_A_17, DA850_EMA_A_18, DA850_EMA_A_19, + DA850_EMA_A_20, DA850_EMA_A_21, DA850_EMA_A_22, DA850_EMA_A_23, -1 }; diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 2c3f418..8de2dbb 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -125,7 +125,6 @@ extern const short da850_rmii_pins[]; extern const short da850_mcasp_pins[]; extern const short da850_lcdcntl_pins[]; extern const short da850_mmcsd0_pins[]; -extern const short da850_nand_pins[]; -extern const short da850_nor_pins[]; +extern const short da850_emif25_pins[]; #endif /* __ASM_ARCH_DAVINCI_DA8XX_H */ -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:38 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:38 -0700 Subject: [PATCH 14/47] DA850: move MII/RMII pin lists to the board file In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-15-git-send-email-khilman@deeprootsystems.com> From: Sergei Shtylyov The CPGMAC pin list in da850.c was incorrectly split into two MII/RMII mode specific pin lists, while what pin group is used is a function of how the board is wired. Copy the pin lists to board-da850-evm.c, renaming them accordingly, and merge the two lists in da850.c into one, da850_cpgmac_pins[], representing the CPGMAC module as a whole... Signed-off-by: Sergei Shtylyov Tested-by: Ben Gardiner Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 21 +++++++++++++++++++-- arch/arm/mach-davinci/da850.c | 12 +++--------- arch/arm/mach-davinci/include/mach/da8xx.h | 1 - 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 482d458..190ebd3 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -600,6 +600,23 @@ static const short da850_evm_lcdc_pins[] = { -1 }; +static const short da850_evm_mii_pins[] = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static const short da850_evm_rmii_pins[] = { + DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, + DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, + DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + static int __init da850_evm_config_emac(void) { void __iomem *cfg_chip3_base; @@ -617,12 +634,12 @@ static int __init da850_evm_config_emac(void) if (rmii_en) { val |= BIT(8); - ret = davinci_cfg_reg_list(da850_rmii_pins); + ret = davinci_cfg_reg_list(da850_evm_rmii_pins); pr_info("EMAC: RMII PHY configured, MII PHY will not be" " functional\n"); } else { val &= ~BIT(8); - ret = davinci_cfg_reg_list(da850_cpgmac_pins); + ret = davinci_cfg_reg_list(da850_evm_mii_pins); pr_info("EMAC: MII PHY configured, RMII PHY will not be" " functional\n"); } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index efb904e..c2a3ce5 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -574,15 +574,9 @@ const short da850_cpgmac_pins[] __initdata = { DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, - DA850_MDIO_D, - -1 -}; - -const short da850_rmii_pins[] __initdata = { - DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, - DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, - DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK, - DA850_MDIO_D, + DA850_MDIO_D, DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, + DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, DA850_RMII_RXER, + DA850_RMII_MHZ_50_CLK, -1 }; diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 8de2dbb..504f2f6 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -121,7 +121,6 @@ extern const short da850_uart2_pins[]; extern const short da850_i2c0_pins[]; extern const short da850_i2c1_pins[]; extern const short da850_cpgmac_pins[]; -extern const short da850_rmii_pins[]; extern const short da850_mcasp_pins[]; extern const short da850_lcdcntl_pins[]; extern const short da850_mmcsd0_pins[]; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:39 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:39 -0700 Subject: [PATCH 15/47] arm: mach-davinci: check irq2ctlr() result In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-16-git-send-email-khilman@deeprootsystems.com> From: Kulikov Vasiliy If irq2ctlr() fails return IRQ_NONE. Also as it can fail make 'ctlr' signed. The semantic patch that finds this problem (many false-positive results): (http://coccinelle.lip6.fr/) // @ r1 @ identifier f; @@ int f(...) { ... } @@ identifier r1.f; type T; unsigned T x; @@ *x = f(...) ... *x > 0 Signed-off-by: Kulikov Vasiliy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/dma.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index 2ede598..6b96698 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -354,10 +354,12 @@ static int irq2ctlr(int irq) static irqreturn_t dma_irq_handler(int irq, void *data) { int i; - unsigned ctlr; + int ctlr; unsigned int cnt = 0; ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; dev_dbg(data, "dma_irq_handler\n"); @@ -408,10 +410,12 @@ static irqreturn_t dma_irq_handler(int irq, void *data) static irqreturn_t dma_ccerr_handler(int irq, void *data) { int i; - unsigned ctlr; + int ctlr; unsigned int cnt = 0; ctlr = irq2ctlr(irq); + if (ctlr < 0) + return IRQ_NONE; dev_dbg(data, "dma_ccerr_handler\n"); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:40 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:40 -0700 Subject: [PATCH 16/47] DA850: Add LPSC id for MMCSD1 peripheral In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-17-git-send-email-khilman@deeprootsystems.com> From: Juha Kuikka Add LPSC id for DA850's MMCSD1 peripheral. Signed-off-by: Juha Kuikka Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/include/mach/psc.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 983da6e..62b0858 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -172,6 +172,7 @@ #define DA8XX_LPSC1_UART2 13 #define DA8XX_LPSC1_LCDC 16 #define DA8XX_LPSC1_PWM 17 +#define DA850_LPSC1_MMC_SD1 18 #define DA8XX_LPSC1_ECAP 20 #define DA830_LPSC1_EQEP 21 #define DA850_LPSC1_TPTC2 21 -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:41 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:41 -0700 Subject: [PATCH 17/47] DA850: Split MMCSD clock into two to support both MMCSD peripherals In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-18-git-send-email-khilman@deeprootsystems.com> From: Juha Kuikka Split mmcsd_clk into mmcsd0_clk and mmcsd1_clk and add davinci_mmc.1 in preparation for adding support for MMCSD1 peripheral in DA850. Signed-off-by: Juha Kuikka Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/da850.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index c2a3ce5..63916b9 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -325,12 +325,19 @@ static struct clk lcdc_clk = { .gpsc = 1, }; -static struct clk mmcsd_clk = { - .name = "mmcsd", +static struct clk mmcsd0_clk = { + .name = "mmcsd0", .parent = &pll0_sysclk2, .lpsc = DA8XX_LPSC0_MMC_SD, }; +static struct clk mmcsd1_clk = { + .name = "mmcsd1", + .parent = &pll0_sysclk2, + .lpsc = DA850_LPSC1_MMC_SD1, + .gpsc = 1, +}; + static struct clk aemif_clk = { .name = "aemif", .parent = &pll0_sysclk3, @@ -377,7 +384,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_emac.1", NULL, &emac_clk), CLK("davinci-mcasp.0", NULL, &mcasp_clk), CLK("da8xx_lcdc.0", NULL, &lcdc_clk), - CLK("davinci_mmc.0", NULL, &mmcsd_clk), + CLK("davinci_mmc.0", NULL, &mmcsd0_clk), + CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), CLK(NULL, NULL, NULL), }; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:42 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:42 -0700 Subject: [PATCH 18/47] DA850: Add MMCSD1 resources, platform device and convenience registration function In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-19-git-send-email-khilman@deeprootsystems.com> From: Juha Kuikka Add resources, platform device and convenience registration function for DA850's second MMC/SD controller (MMCSD1). Signed-off-by: Juha Kuikka Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices-da8xx.c | 39 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 1 + 2 files changed, 40 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 52bc7b1..caeb7f4 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -24,6 +24,7 @@ #include "clock.h" #define DA8XX_TPCC_BASE 0x01c00000 +#define DA850_MMCSD1_BASE 0x01e1b000 #define DA850_TPCC1_BASE 0x01e30000 #define DA8XX_TPTC0_BASE 0x01c08000 #define DA8XX_TPTC1_BASE 0x01c08400 @@ -566,6 +567,44 @@ int __init da8xx_register_mmcsd0(struct davinci_mmc_config *config) return platform_device_register(&da8xx_mmcsd0_device); } +#ifdef CONFIG_ARCH_DAVINCI_DA850 +static struct resource da850_mmcsd1_resources[] = { + { /* registers */ + .start = DA850_MMCSD1_BASE, + .end = DA850_MMCSD1_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { /* interrupt */ + .start = IRQ_DA850_MMCSDINT0_1, + .end = IRQ_DA850_MMCSDINT0_1, + .flags = IORESOURCE_IRQ, + }, + { /* DMA RX */ + .start = EDMA_CTLR_CHAN(1, 28), + .end = EDMA_CTLR_CHAN(1, 28), + .flags = IORESOURCE_DMA, + }, + { /* DMA TX */ + .start = EDMA_CTLR_CHAN(1, 29), + .end = EDMA_CTLR_CHAN(1, 29), + .flags = IORESOURCE_DMA, + }, +}; + +static struct platform_device da850_mmcsd1_device = { + .name = "davinci_mmc", + .id = 1, + .num_resources = ARRAY_SIZE(da850_mmcsd1_resources), + .resource = da850_mmcsd1_resources, +}; + +int __init da850_register_mmcsd1(struct davinci_mmc_config *config) +{ + da850_mmcsd1_device.dev.platform_data = config; + return platform_device_register(&da850_mmcsd1_device); +} +#endif + static struct resource da8xx_rtc_resources[] = { { .start = DA8XX_RTC_BASE, diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 504f2f6..4247b3f 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -76,6 +76,7 @@ int da8xx_register_usb11(struct da8xx_ohci_root_hub *pdata); int da8xx_register_emac(void); int da8xx_register_lcdc(struct da8xx_lcdc_platform_data *pdata); int da8xx_register_mmcsd0(struct davinci_mmc_config *config); +int da850_register_mmcsd1(struct davinci_mmc_config *config); void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata); int da8xx_register_rtc(void); int da850_register_cpufreq(char *async_clk); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:43 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:43 -0700 Subject: [PATCH 19/47] davinci: dm365 evm: use EDMAQ_3 as the audio DMA queue In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-20-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori By default the audio driver uses EDMAQ_0 as the DMA queue, but on DM365 this queue is specially designed for video transfers with a large fifo size. Having both audio and video transfers on the same queue leads to noise on the audio side. This patch changes the audio queue number for DM365 to EDMAQ_3. Signed-off-by: Sekhar Nori Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm365-evm.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 84acef1..bdea2da 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -175,7 +175,9 @@ static struct at24_platform_data eeprom_info = { .context = (void *)0x7f00, }; -static struct snd_platform_data dm365_evm_snd_data; +static struct snd_platform_data dm365_evm_snd_data = { + .asp_chan_q = EVENTQ_3, +}; static struct i2c_board_info i2c_info[] = { { -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:44 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:44 -0700 Subject: [PATCH 20/47] davinci: add support for aemif timing configuration In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-21-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori This patch adds support to configure the AEMIF interface with supplied timing values. Since this capability is useful both from NOR and NAND flashes, it is provided as a new interface and in a file of its own. AEMIF timing configuration is required in cases: 1) Where the AEMIF clock rate can change at runtime (a side affect of cpu frequency change). 2) Where U-Boot does not support NAND/NOR but supports other media like SPI Flash or MMC/SD and thus does not care about setting up the AEMIF timing for kernel to use. 3) Where U-Boot just hasn't configured the timing values and cannot be upgraded because the box is already in the field. Since there is now a header file for AEMIF interface, the common (non-NAND specific) defines for AEMIF registers have been moved from nand.h into the newly created aemif.h Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/Makefile | 2 +- arch/arm/mach-davinci/aemif.c | 133 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/aemif.h | 36 ++++++++ arch/arm/mach-davinci/include/mach/nand.h | 3 - drivers/mtd/nand/davinci_nand.c | 1 + 5 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 arch/arm/mach-davinci/aemif.c create mode 100644 arch/arm/mach-davinci/include/mach/aemif.h diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index eab4c0f..77a0f71 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o io.o psc.o \ - gpio.o dma.o usb.o common.o sram.o + gpio.o dma.o usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/aemif.c b/arch/arm/mach-davinci/aemif.c new file mode 100644 index 0000000..9c3f500 --- /dev/null +++ b/arch/arm/mach-davinci/aemif.c @@ -0,0 +1,133 @@ +/* + * AEMIF support for DaVinci SoCs + * + * Copyright (C) 2010 Texas Instruments Incorporated. http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include + +/* Timing value configuration */ + +#define TA(x) ((x) << 2) +#define RHOLD(x) ((x) << 4) +#define RSTROBE(x) ((x) << 7) +#define RSETUP(x) ((x) << 13) +#define WHOLD(x) ((x) << 17) +#define WSTROBE(x) ((x) << 20) +#define WSETUP(x) ((x) << 26) + +#define TA_MAX 0x3 +#define RHOLD_MAX 0x7 +#define RSTROBE_MAX 0x3f +#define RSETUP_MAX 0xf +#define WHOLD_MAX 0x7 +#define WSTROBE_MAX 0x3f +#define WSETUP_MAX 0xf + +#define TIMING_MASK (TA(TA_MAX) | \ + RHOLD(RHOLD_MAX) | \ + RSTROBE(RSTROBE_MAX) | \ + RSETUP(RSETUP_MAX) | \ + WHOLD(WHOLD_MAX) | \ + WSTROBE(WSTROBE_MAX) | \ + WSETUP(WSETUP_MAX)) + +/* + * aemif_calc_rate - calculate timing data. + * @wanted: The cycle time needed in nanoseconds. + * @clk: The input clock rate in kHz. + * @max: The maximum divider value that can be programmed. + * + * On success, returns the calculated timing value minus 1 for easy + * programming into AEMIF timing registers, else negative errno. + */ +static int aemif_calc_rate(int wanted, unsigned long clk, int max) +{ + int result; + + result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1; + + pr_debug("%s: result %d from %ld, %d\n", __func__, result, clk, wanted); + + /* It is generally OK to have a more relaxed timing than requested... */ + if (result < 0) + result = 0; + + /* ... But configuring tighter timings is not an option. */ + else if (result > max) + result = -EINVAL; + + return result; +} + +/** + * davinci_aemif_setup_timing - setup timing values for a given AEMIF interface + * @t: timing values to be progammed + * @base: The virtual base address of the AEMIF interface + * @cs: chip-select to program the timing values for + * + * This function programs the given timing values (in real clock) into the + * AEMIF registers taking the AEMIF clock into account. + * + * This function does not use any locking while programming the AEMIF + * because it is expected that there is only one user of a given + * chip-select. + * + * Returns 0 on success, else negative errno. + */ +int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, + void __iomem *base, unsigned cs) +{ + unsigned set, val; + unsigned ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup; + unsigned offset = A1CR_OFFSET + cs * 4; + struct clk *aemif_clk; + unsigned long clkrate; + + if (!t) + return 0; /* Nothing to do */ + + aemif_clk = clk_get(NULL, "aemif"); + if (IS_ERR(aemif_clk)) + return PTR_ERR(aemif_clk); + + clkrate = clk_get_rate(aemif_clk); + + clkrate /= 1000; /* turn clock into kHz for ease of use */ + + ta = aemif_calc_rate(t->ta, clkrate, TA_MAX); + rhold = aemif_calc_rate(t->rhold, clkrate, RHOLD_MAX); + rstrobe = aemif_calc_rate(t->rstrobe, clkrate, RSTROBE_MAX); + rsetup = aemif_calc_rate(t->rsetup, clkrate, RSETUP_MAX); + whold = aemif_calc_rate(t->whold, clkrate, WHOLD_MAX); + wstrobe = aemif_calc_rate(t->wstrobe, clkrate, WSTROBE_MAX); + wsetup = aemif_calc_rate(t->wsetup, clkrate, WSETUP_MAX); + + if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 || + whold < 0 || wstrobe < 0 || wsetup < 0) { + pr_err("%s: cannot get suitable timings\n", __func__); + return -EINVAL; + } + + set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) | + WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup); + + val = __raw_readl(base + offset); + val &= ~TIMING_MASK; + val |= set; + __raw_writel(val, base + offset); + + return 0; +} +EXPORT_SYMBOL(davinci_aemif_setup_timing); diff --git a/arch/arm/mach-davinci/include/mach/aemif.h b/arch/arm/mach-davinci/include/mach/aemif.h new file mode 100644 index 0000000..05b2934 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/aemif.h @@ -0,0 +1,36 @@ +/* + * TI DaVinci AEMIF support + * + * Copyright 2010 (C) Texas Instruments, Inc. http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _MACH_DAVINCI_AEMIF_H +#define _MACH_DAVINCI_AEMIF_H + +#define NRCSR_OFFSET 0x00 +#define AWCCR_OFFSET 0x04 +#define A1CR_OFFSET 0x10 + +#define ACR_ASIZE_MASK 0x3 +#define ACR_EW_MASK BIT(30) +#define ACR_SS_MASK BIT(31) + +/* All timings in nanoseconds */ +struct davinci_aemif_timing { + u8 wsetup; + u8 wstrobe; + u8 whold; + + u8 rsetup; + u8 rstrobe; + u8 rhold; + + u8 ta; +}; + +int davinci_aemif_setup_timing(struct davinci_aemif_timing *t, + void __iomem *base, unsigned cs); +#endif diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h index b2ad809..b5893f0 100644 --- a/arch/arm/mach-davinci/include/mach/nand.h +++ b/arch/arm/mach-davinci/include/mach/nand.h @@ -30,9 +30,6 @@ #include -#define NRCSR_OFFSET 0x00 -#define AWCCR_OFFSET 0x04 -#define A1CR_OFFSET 0x10 #define NANDFCR_OFFSET 0x60 #define NANDFSR_OFFSET 0x64 #define NANDF1ECC_OFFSET 0x70 diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 2ac7367..8e2d56c 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -35,6 +35,7 @@ #include #include +#include #include -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:45 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:45 -0700 Subject: [PATCH 21/47] nand: davinci: add support for timing configuration In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-22-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori This patch modifies the DaVinci NAND driver to use the new AEMIF timing setup API to configure the NAND access timings. Earlier, AEMIF configuration was being done as a special case for DM644x board, but now more boards emerge which have capability to boot for other media (SPI flash, NOR flash) and have the kernel access NAND flash. This means that kernel cannot always depend on the bootloader to setup the NAND. Also, on platforms such as da850/omap-l138, the aemif input frequency changes as cpu frequency changes; necessiating re-calculation of timimg values as part of cpufreq transtitions. This patch forms the basis for adding that support. Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: Artem Bityutskiy --- arch/arm/mach-davinci/include/mach/nand.h | 3 + drivers/mtd/nand/davinci_nand.c | 60 ++++++++++------------------ 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h index b5893f0..0251510 100644 --- a/arch/arm/mach-davinci/include/mach/nand.h +++ b/arch/arm/mach-davinci/include/mach/nand.h @@ -80,6 +80,9 @@ struct davinci_nand_pdata { /* platform_data */ /* Main and mirror bbt descriptor overrides */ struct nand_bbt_descr *bbt_td; struct nand_bbt_descr *bbt_md; + + /* Access timings */ + struct davinci_aemif_timing *timing; }; #endif /* __ARCH_ARM_DAVINCI_NAND_H */ diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 8e2d56c..8beb0d0 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -75,6 +75,8 @@ struct davinci_nand_info { uint32_t mask_cle; uint32_t core_chipsel; + + struct davinci_aemif_timing *timing; }; static DEFINE_SPINLOCK(davinci_nand_lock); @@ -479,36 +481,6 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd) return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0); } -static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info) -{ - uint32_t regval, a1cr; - - /* - * NAND FLASH timings @ PLL1 == 459 MHz - * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz - * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns - */ - regval = 0 - | (0 << 31) /* selectStrobe */ - | (0 << 30) /* extWait (never with NAND) */ - | (1 << 26) /* writeSetup 10 ns */ - | (3 << 20) /* writeStrobe 40 ns */ - | (1 << 17) /* writeHold 10 ns */ - | (0 << 13) /* readSetup 10 ns */ - | (3 << 7) /* readStrobe 60 ns */ - | (0 << 4) /* readHold 10 ns */ - | (3 << 2) /* turnAround ?? ns */ - | (0 << 0) /* asyncSize 8-bit bus */ - ; - a1cr = davinci_nand_readl(info, A1CR_OFFSET); - if (a1cr != regval) { - dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \ - "reg to 0x%08x, was 0x%08x, should be done by " \ - "bootloader.\n", regval, a1cr); - davinci_nand_writel(info, A1CR_OFFSET, regval); - } -} - /*----------------------------------------------------------------------*/ /* An ECC layout for using 4-bit ECC with small-page flash, storing @@ -612,6 +584,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) info->chip.options = pdata->options; info->chip.bbt_td = pdata->bbt_td; info->chip.bbt_md = pdata->bbt_md; + info->timing = pdata->timing; info->ioaddr = (uint32_t __force) vaddr; @@ -689,15 +662,25 @@ static int __init nand_davinci_probe(struct platform_device *pdev) goto err_clk_enable; } - /* EMIF timings should normally be set by the boot loader, - * especially after boot-from-NAND. The *only* reason to - * have this special casing for the DM6446 EVM is to work - * with boot-from-NOR ... with CS0 manually re-jumpered - * (after startup) so it addresses the NAND flash, not NOR. - * Even for dev boards, that's unusually rude... + /* + * Setup Async configuration register in case we did not boot from + * NAND and so bootloader did not bother to set it up. */ - if (machine_is_davinci_evm()) - nand_dm6446evm_flash_init(info); + val = davinci_nand_readl(info, A1CR_OFFSET + info->core_chipsel * 4); + + /* Extended Wait is not valid and Select Strobe mode is not used */ + val &= ~(ACR_ASIZE_MASK | ACR_EW_MASK | ACR_SS_MASK); + if (info->chip.options & NAND_BUSWIDTH_16) + val |= 0x1; + + davinci_nand_writel(info, A1CR_OFFSET + info->core_chipsel * 4, val); + + ret = davinci_aemif_setup_timing(info->timing, info->base, + info->core_chipsel); + if (ret < 0) { + dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); + goto err_timing; + } spin_lock_irq(&davinci_nand_lock); @@ -810,6 +793,7 @@ syndrome_done: return 0; err_scan: +err_timing: clk_disable(info->clk); err_clk_enable: -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:46 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:46 -0700 Subject: [PATCH 22/47] davinci: dm644x evm: setup NAND flash timing In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-23-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori The DM644x EVM nand flash timing was earlier being done as a special case in the NAND driver itself. With the NAND driver now capable of progamming the AEMIF interface using timing data passed from the platform, the timing values are being moved into their rightful place in the EVM specific board file. The values being programmed match what was being done earlier and thus do not represent any change in performance/functionality. Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm644x-evm.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 34c8b41..65bb940 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -37,6 +37,7 @@ #include #include #include +#include #define DM644X_EVM_PHY_MASK (0x2) #define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ @@ -137,11 +138,22 @@ static struct mtd_partition davinci_evm_nandflash_partition[] = { */ }; +static struct davinci_aemif_timing davinci_evm_nandflash_timing = { + .wsetup = 20, + .wstrobe = 40, + .whold = 20, + .rsetup = 10, + .rstrobe = 40, + .rhold = 10, + .ta = 40, +}; + static struct davinci_nand_pdata davinci_evm_nandflash_data = { .parts = davinci_evm_nandflash_partition, .nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition), .ecc_mode = NAND_ECC_HW, .options = NAND_USE_FLASH_BBT, + .timing = &davinci_evm_nandflash_timing, }; static struct resource davinci_evm_nandflash_resource[] = { -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:47 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:47 -0700 Subject: [PATCH 23/47] davinci: am17x/da830/omap-l137 evm: setup NAND flash timing In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-24-git-send-email-khilman@deeprootsystems.com> From: Sudhakar Rajashekhara Setup the NAND flash timings for DA830 EVM. Before configuring the timing values, throughput calculation using dd command yielded 477 kB/s write and 970 kB/s read speed. After the timing configuration, the throughput was measured to be 2.5 MB/s write and 5.1 MB/s read. [Mukul Bhatnagar: actual calculation of timing values from the NAND datasheet] Signed-off-by: Sudhakar Rajashekhara Cc: Mukul Bhatnagar Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 292e8b7..de82739 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -29,6 +29,7 @@ #include #include #include +#include #define DA830_EVM_PHY_MASK 0x0 #define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ @@ -360,6 +361,16 @@ static struct nand_bbt_descr da830_evm_nand_bbt_mirror_descr = { .pattern = da830_evm_nand_mirror_pattern }; +static struct davinci_aemif_timing da830_evm_nandflash_timing = { + .wsetup = 24, + .wstrobe = 21, + .whold = 14, + .rsetup = 19, + .rstrobe = 50, + .rhold = 0, + .ta = 20, +}; + static struct davinci_nand_pdata da830_evm_nand_pdata = { .parts = da830_evm_nand_partitions, .nr_parts = ARRAY_SIZE(da830_evm_nand_partitions), @@ -368,6 +379,7 @@ static struct davinci_nand_pdata da830_evm_nand_pdata = { .options = NAND_USE_FLASH_BBT, .bbt_td = &da830_evm_nand_bbt_main_descr, .bbt_md = &da830_evm_nand_bbt_mirror_descr, + .timing = &da830_evm_nandflash_timing, }; static struct resource da830_evm_nand_resources[] = { -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:48 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:48 -0700 Subject: [PATCH 24/47] davinci: am18x/da850/omap-l138 evm: setup NAND flash timing In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-25-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Setup the NAND flash timings for DA850 EVM Before configuring the timing values, throughput calculation using dd command yielded 469 kB/s write and 966 kB/s read speed. After the timing configuration, the throughput was measured to be 2.4 MB/s write and 5 MB/s read. [Mukul Bhatnagar: actual calculation of timing values from the NAND datasheet] Signed-off-by: Sekhar Nori Cc: Mukul Bhatnagar Acked-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da850-evm.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 190ebd3..c1d45d7 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -36,6 +36,7 @@ #include #include #include +#include #define DA850_EVM_PHY_MASK 0x1 #define DA850_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ @@ -143,12 +144,23 @@ static struct mtd_partition da850_evm_nandflash_partition[] = { }, }; +static struct davinci_aemif_timing da850_evm_nandflash_timing = { + .wsetup = 24, + .wstrobe = 21, + .whold = 14, + .rsetup = 19, + .rstrobe = 50, + .rhold = 0, + .ta = 20, +}; + static struct davinci_nand_pdata da850_evm_nandflash_data = { .parts = da850_evm_nandflash_partition, .nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition), .ecc_mode = NAND_ECC_HW, .ecc_bits = 4, .options = NAND_USE_FLASH_BBT, + .timing = &da850_evm_nandflash_timing, }; static struct resource da850_evm_nandflash_resource[] = { -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:49 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:49 -0700 Subject: [PATCH 25/47] davinci: dm6467t evm: setup NAND flash timing In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-26-git-send-email-khilman@deeprootsystems.com> From: Sekhar Nori Setup NAND flash timing on DM6467T EVM. Without the timing setup, the NAND flash on DM6467T RevC EVM reports a number of random bad blocks because of read errors. Also, with this, copying a 100M file on RevB EVM takes ~35 sec against 1 minute 30 seconds earlier. Signed-off-by: Sekhar Nori Acked-by: Kevin Hilman Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-dm646x-evm.c | 14 ++++++++++++++ 1 files changed, 14 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 4502f34..5a29955 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "clock.h" @@ -71,6 +72,16 @@ static struct mtd_partition davinci_nand_partitions[] = { } }; +static struct davinci_aemif_timing dm6467tevm_nandflash_timing = { + .wsetup = 29, + .wstrobe = 24, + .whold = 14, + .rsetup = 19, + .rstrobe = 33, + .rhold = 0, + .ta = 29, +}; + static struct davinci_nand_pdata davinci_nand_data = { .mask_cle = 0x80000, .mask_ale = 0x40000, @@ -763,6 +774,9 @@ static __init void evm_init(void) dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); dm646x_init_mcasp1(&dm646x_evm_snd_data[1]); + if (machine_is_davinci_dm6467tevm()) + davinci_nand_data.timing = &dm6467tevm_nandflash_timing; + platform_device_register(&davinci_nand_device); dm646x_init_edma(dm646x_edma_rsv); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:50 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:50 -0700 Subject: [PATCH 26/47] davinci: Add machine checks to DA8XX serial console init routines In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-27-git-send-email-khilman@deeprootsystems.com> From: Michael Williamson This patch adds machine checks in the serial console init routines for the DA8XX EVM boards. This is needed because there are other DA8XX based machines that use a different UART/tty as the console and may be included in a common kernel build. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 3 +++ arch/arm/mach-davinci/board-da850-evm.c | 3 +++ 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index de82739..ef1ab0b 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -598,6 +598,9 @@ static __init void da830_evm_init(void) #ifdef CONFIG_SERIAL_8250_CONSOLE static int __init da830_evm_console_init(void) { + if (!machine_is_davinci_da830_evm()) + return 0; + return add_preferred_console("ttyS", 2, "115200"); } console_initcall(da830_evm_console_init); diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index c1d45d7..ac2297c 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -859,6 +859,9 @@ static __init void da850_evm_init(void) #ifdef CONFIG_SERIAL_8250_CONSOLE static int __init da850_evm_console_init(void) { + if (!machine_is_davinci_da850_evm()) + return 0; + return add_preferred_console("ttyS", 2, "115200"); } console_initcall(da850_evm_console_init); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:51 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:51 -0700 Subject: [PATCH 27/47] davinci: Add CONFIG_REGULATOR_DUMMY to DA8XX defconfig file. In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-28-git-send-email-khilman@deeprootsystems.com> From: Michael Williamson In order to support reference DA8XX machines not providing a voltage regulator control for the core voltage, the REGULATOR_DUMMY option is required. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman --- arch/arm/configs/da8xx_omapl_defconfig | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig index ba66705..3952a4e 100644 --- a/arch/arm/configs/da8xx_omapl_defconfig +++ b/arch/arm/configs/da8xx_omapl_defconfig @@ -79,6 +79,7 @@ CONFIG_I2C_DAVINCI=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_DUMMY=y CONFIG_REGULATOR_TPS6507X=y CONFIG_FB=y CONFIG_FB_DA8XX=y -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:52 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:52 -0700 Subject: [PATCH 28/47] davinci: Initial support for MityDSP-L138/MityARM-1808 In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-29-git-send-email-khilman@deeprootsystems.com> From: Michael Williamson This patch adds initial support for the MityDSP-L138 and MityDSP-1808 system on Module (SOM) under the machine name "mityomapl138". These SOMs are based on the da850 davinci CPU architecture. Information on these SOMs may be found at http://www.mitydsp.com. Basic support for the console UART, NAND, and EMAC (MII interface) is included in this patch. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman --- arch/arm/configs/da8xx_omapl_defconfig | 1 + arch/arm/mach-davinci/Kconfig | 8 + arch/arm/mach-davinci/Makefile | 1 + arch/arm/mach-davinci/board-mityomapl138.c | 221 +++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/uncompress.h | 1 + 5 files changed, 232 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/board-mityomapl138.c diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig index 3952a4e..f8a47ee 100644 --- a/arch/arm/configs/da8xx_omapl_defconfig +++ b/arch/arm/configs/da8xx_omapl_defconfig @@ -17,6 +17,7 @@ CONFIG_MODVERSIONS=y CONFIG_ARCH_DAVINCI=y CONFIG_ARCH_DAVINCI_DA830=y CONFIG_ARCH_DAVINCI_DA850=y +CONFIG_MACH_MITYOMAPL138=y CONFIG_DAVINCI_RESET_CLOCKS=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 2bf03e9..9aca60c 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -185,6 +185,14 @@ config MACH_TNETV107X help Say Y here to select the TI TNETV107X Evaluation Module. +config MACH_MITYOMAPL138 + bool "Critical Link MityDSP-L138/MityARM-1808 SoM" + depends on ARCH_DAVINCI_DA850 + help + Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 + System on Module. Information on this SoM may be found at + http://www.mitydsp.com + config DAVINCI_MUX bool "DAVINCI multiplexing support" depends on ARCH_DAVINCI diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index 77a0f71..a7a70d1 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o +obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o # Power Management obj-$(CONFIG_CPU_FREQ) += cpufreq.o diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c new file mode 100644 index 0000000..7146916 --- /dev/null +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -0,0 +1,221 @@ +/* + * Critical Link MityOMAP-L138 SoM + * + * Copyright (C) 2010 Critical Link LLC - http://www.criticallink.com + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MITYOMAPL138_PHY_MASK 0x08 /* hardcoded for now */ +#define MITYOMAPL138_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ + +/* + * MityDSP-L138 includes a 256 MByte large-page NAND flash + * (128K blocks). + */ +struct mtd_partition mityomapl138_nandflash_partition[] = { + { + .name = "rootfs", + .offset = 0, + .size = SZ_128M, + .mask_flags = 0, /* MTD_WRITEABLE, */ + }, + { + .name = "homefs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + .mask_flags = 0, + }, +}; + +static struct davinci_nand_pdata mityomapl138_nandflash_data = { + .parts = mityomapl138_nandflash_partition, + .nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition), + .ecc_mode = NAND_ECC_HW, + .options = NAND_USE_FLASH_BBT | NAND_BUSWIDTH_16, + .ecc_bits = 1, /* 4 bit mode is not supported with 16 bit NAND */ +}; + +static struct resource mityomapl138_nandflash_resource[] = { + { + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + SZ_512K + 2 * SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mityomapl138_nandflash_device = { + .name = "davinci_nand", + .id = 0, + .dev = { + .platform_data = &mityomapl138_nandflash_data, + }, + .num_resources = ARRAY_SIZE(mityomapl138_nandflash_resource), + .resource = mityomapl138_nandflash_resource, +}; + +static struct platform_device *mityomapl138_devices[] __initdata = { + &mityomapl138_nandflash_device, +}; + +static void __init mityomapl138_setup_nand(void) +{ + platform_add_devices(mityomapl138_devices, + ARRAY_SIZE(mityomapl138_devices)); +} + +static struct davinci_uart_config mityomapl138_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +static const short mityomap_mii_pins[] = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static const short mityomap_rmii_pins[] = { + DA850_RMII_TXD_0, DA850_RMII_TXD_1, DA850_RMII_TXEN, + DA850_RMII_CRS_DV, DA850_RMII_RXD_0, DA850_RMII_RXD_1, + DA850_RMII_RXER, DA850_RMII_MHZ_50_CLK, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static void __init mityomapl138_config_emac(void) +{ + void __iomem *cfg_chip3_base; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + soc_info->emac_pdata->rmii_en = 0; /* hardcoded for now */ + + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + val = __raw_readl(cfg_chip3_base); + + if (soc_info->emac_pdata->rmii_en) { + val |= BIT(8); + ret = davinci_cfg_reg_list(mityomap_rmii_pins); + pr_info("RMII PHY configured\n"); + } else { + val &= ~BIT(8); + ret = davinci_cfg_reg_list(mityomap_mii_pins); + pr_info("MII PHY configured\n"); + } + + if (ret) { + pr_warning("mii/rmii mux setup failed: %d\n", ret); + return; + } + + /* configure the CFGCHIP3 register for RMII or MII */ + __raw_writel(val, cfg_chip3_base); + + soc_info->emac_pdata->phy_mask = MITYOMAPL138_PHY_MASK; + pr_debug("setting phy_mask to %x\n", soc_info->emac_pdata->phy_mask); + soc_info->emac_pdata->mdio_max_freq = MITYOMAPL138_MDIO_FREQUENCY; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("emac registration failed: %d\n", ret); +} + +static struct davinci_pm_config da850_pm_pdata = { + .sleepcount = 128, +}; + +static struct platform_device da850_pm_device = { + .name = "pm-davinci", + .dev = { + .platform_data = &da850_pm_pdata, + }, + .id = -1, +}; + +static void __init mityomapl138_init(void) +{ + int ret; + + /* for now, no special EDMA channels are reserved */ + ret = da850_register_edma(NULL); + if (ret) + pr_warning("edma registration failed: %d\n", ret); + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("watchdog registration failed: %d\n", ret); + + davinci_serial_init(&mityomapl138_uart_config); + + mityomapl138_setup_nand(); + + mityomapl138_config_emac(); + + ret = da8xx_register_rtc(); + if (ret) + pr_warning("rtc setup failed: %d\n", ret); + + ret = da850_register_cpufreq("pll0_sysclk3"); + if (ret) + pr_warning("cpufreq registration failed: %d\n", ret); + + ret = da8xx_register_cpuidle(); + if (ret) + pr_warning("cpuidle registration failed: %d\n", ret); + + ret = da850_register_pm(&da850_pm_device); + if (ret) + pr_warning("da850_evm_init: suspend registration failed: %d\n", + ret); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init mityomapl138_console_init(void) +{ + if (!machine_is_mityomapl138()) + return 0; + + return add_preferred_console("ttyS", 1, "115200"); +} +console_initcall(mityomapl138_console_init); +#endif + +static void __init mityomapl138_map_io(void) +{ + da850_init(); +} + +MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") + .phys_io = IO_PHYS, + .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, + .boot_params = (DA8XX_DDR_BASE + 0x100), + .map_io = mityomapl138_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = mityomapl138_init, +MACHINE_END diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 15a6192..d370391 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -88,6 +88,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) /* DA8xx boards */ DEBUG_LL_DA8XX(davinci_da830_evm, 2); DEBUG_LL_DA8XX(davinci_da850_evm, 2); + DEBUG_LL_DA8XX(mityomapl138, 1); /* TNETV107x boards */ DEBUG_LL_TNETV107X(tnetv107x, 1); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:53 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:53 -0700 Subject: [PATCH 29/47] davinci: add idcode for tnetv107x rev 1.1/1.2 In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-30-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds an entry into the idcode table for tnetv107x silicon revision 1.1 and 1.2 devices. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/tnetv107x.c | 9 ++++++++- 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index 06d2ac9..daeae06 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -581,7 +581,14 @@ static struct davinci_id ids[] = { .part_no = 0xb8a1, .manufacturer = 0x017, .cpu_id = DAVINCI_CPU_ID_TNETV107X, - .name = "tnetv107x rev1.0", + .name = "tnetv107x rev 1.0", + }, + { + .variant = 0x1, + .part_no = 0xb8a1, + .manufacturer = 0x017, + .cpu_id = DAVINCI_CPU_ID_TNETV107X, + .name = "tnetv107x rev 1.1/1.2", }, }; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:54 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:54 -0700 Subject: [PATCH 30/47] davinci: Add I2C0 devices to MityDSP-L138/MityARM-1808 platform In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-31-git-send-email-khilman@deeprootsystems.com> From: Michael Williamson This patch adds the i2c0 bus and attached devices to the MityDSP-L138 and MityARM-1808 davinci SoM. Included is a TPS65023 voltage regulator needed for power management and a small 24c02 EPROM that contains factory configuration data. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-mityomapl138.c | 145 ++++++++++++++++++++++++++++ 1 files changed, 145 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 7146916..84d5aff 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -25,6 +27,141 @@ #define MITYOMAPL138_PHY_MASK 0x08 /* hardcoded for now */ #define MITYOMAPL138_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ +static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* TPS65023 voltage regulator support */ +/* 1.2V Core */ +struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { + { + .supply = "cvdd", + }, +}; + +/* 1.8V */ +struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { + { + .supply = "usb0_vdda18", + }, + { + .supply = "usb1_vdda18", + }, + { + .supply = "ddr_dvdd18", + }, + { + .supply = "sata_vddr", + }, +}; + +/* 1.2V */ +struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { + { + .supply = "sata_vdd", + }, + { + .supply = "usb_cvdd", + }, + { + .supply = "pll0_vdda", + }, + { + .supply = "pll1_vdda", + }, +}; + +/* 1.8V Aux LDO, not used */ +struct regulator_consumer_supply tps65023_ldo1_consumers[] = { + { + .supply = "1.8v_aux", + }, +}; + +/* FPGA VCC Aux (2.5 or 3.3) LDO */ +struct regulator_consumer_supply tps65023_ldo2_consumers[] = { + { + .supply = "vccaux", + }, +}; + +struct regulator_init_data tps65023_regulator_data[] = { + /* dcdc1 */ + { + .constraints = { + .min_uV = 1150000, + .max_uV = 1350000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc1_consumers), + .consumer_supplies = tps65023_dcdc1_consumers, + }, + /* dcdc2 */ + { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc2_consumers), + .consumer_supplies = tps65023_dcdc2_consumers, + }, + /* dcdc3 */ + { + .constraints = { + .min_uV = 1200000, + .max_uV = 1200000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_dcdc3_consumers), + .consumer_supplies = tps65023_dcdc3_consumers, + }, + /* ldo1 */ + { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo1_consumers), + .consumer_supplies = tps65023_ldo1_consumers, + }, + /* ldo2 */ + { + .constraints = { + .min_uV = 2500000, + .max_uV = 3300000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, + .boot_on = 1, + }, + .num_consumer_supplies = ARRAY_SIZE(tps65023_ldo2_consumers), + .consumer_supplies = tps65023_ldo2_consumers, + }, +}; + +static struct i2c_board_info __initdata mityomap_tps65023_info[] = { + { + I2C_BOARD_INFO("tps65023", 0x48), + .platform_data = &tps65023_regulator_data[0], + }, + { + I2C_BOARD_INFO("24c02", 0x50), + }, +}; + +static int __init pmic_tps65023_init(void) +{ + return i2c_register_board_info(1, mityomap_tps65023_info, + ARRAY_SIZE(mityomap_tps65023_info)); +} + /* * MityDSP-L138 includes a 256 MByte large-page NAND flash * (128K blocks). @@ -172,6 +309,14 @@ static void __init mityomapl138_init(void) davinci_serial_init(&mityomapl138_uart_config); + ret = da8xx_register_i2c(0, &mityomap_i2c_0_pdata); + if (ret) + pr_warning("i2c0 registration failed: %d\n", ret); + + ret = pmic_tps65023_init(); + if (ret) + pr_warning("TPS65023 PMIC init failed: %d\n", ret); + mityomapl138_setup_nand(); mityomapl138_config_emac(); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:55 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:55 -0700 Subject: [PATCH 31/47] net: davinci_emac: separate out davinci mdio In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-32-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy Davinci's MDIO controller is present on other TI devices, without an accompanying EMAC. For example, on tnetv107x, the same MDIO module is used in conjunction with a 3-port switch hardware. By separating the MDIO controller code into its own platform driver, this patch allows common logic to be reused on such platforms. Signed-off-by: Cyril Chemparathy Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/davinci_mdio.c | 475 ++++++++++++++++++++++++++++++++++++++++++ include/linux/davinci_emac.h | 4 + 4 files changed, 490 insertions(+), 0 deletions(-) create mode 100644 drivers/net/davinci_mdio.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2cc81a5..c5c86e0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -958,6 +958,16 @@ config TI_DAVINCI_EMAC To compile this driver as a module, choose M here: the module will be called davinci_emac_driver. This is recommended. +config TI_DAVINCI_MDIO + tristate "TI DaVinci MDIO Support" + depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) + select PHYLIB + help + This driver supports TI's DaVinci MDIO module. + + To compile this driver as a module, choose M here: the module + will be called davinci_mdio. This is recommended. + config DM9000 tristate "DM9000 support" depends on ARM || BLACKFIN || MIPS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3e8f150..d38a7ab 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_MDIO) += mdio.o obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o +obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_E1000E) += e1000e/ diff --git a/drivers/net/davinci_mdio.c b/drivers/net/davinci_mdio.c new file mode 100644 index 0000000..7615040 --- /dev/null +++ b/drivers/net/davinci_mdio.c @@ -0,0 +1,475 @@ +/* + * DaVinci MDIO Module driver + * + * Copyright (C) 2010 Texas Instruments. + * + * Shamelessly ripped out of davinci_emac.c, original copyrights follow: + * + * Copyright (C) 2009 Texas Instruments. + * + * --------------------------------------------------------------------------- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * --------------------------------------------------------------------------- + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This timeout definition is a worst-case ultra defensive measure against + * unexpected controller lock ups. Ideally, we should never ever hit this + * scenario in practice. + */ +#define MDIO_TIMEOUT 100 /* msecs */ + +#define PHY_REG_MASK 0x1f +#define PHY_ID_MASK 0x1f + +#define DEF_OUT_FREQ 2200000 /* 2.2 MHz */ + +struct davinci_mdio_regs { + u32 version; + u32 control; +#define CONTROL_IDLE BIT(31) +#define CONTROL_ENABLE BIT(30) +#define CONTROL_MAX_DIV (0xff) + + u32 alive; + u32 link; + u32 linkintraw; + u32 linkintmasked; + u32 __reserved_0[2]; + u32 userintraw; + u32 userintmasked; + u32 userintmaskset; + u32 userintmaskclr; + u32 __reserved_1[20]; + + struct { + u32 access; +#define USERACCESS_GO BIT(31) +#define USERACCESS_WRITE BIT(30) +#define USERACCESS_ACK BIT(29) +#define USERACCESS_READ (0) +#define USERACCESS_DATA (0xffff) + + u32 physel; + } user[0]; +}; + +struct mdio_platform_data default_pdata = { + .bus_freq = DEF_OUT_FREQ, +}; + +struct davinci_mdio_data { + struct mdio_platform_data pdata; + struct davinci_mdio_regs __iomem *regs; + spinlock_t lock; + struct clk *clk; + struct device *dev; + struct mii_bus *bus; + bool suspended; + unsigned long access_time; /* jiffies */ +}; + +static void __davinci_mdio_reset(struct davinci_mdio_data *data) +{ + u32 mdio_in, div, mdio_out_khz, access_time; + + mdio_in = clk_get_rate(data->clk); + div = (mdio_in / data->pdata.bus_freq) - 1; + if (div > CONTROL_MAX_DIV) + div = CONTROL_MAX_DIV; + + /* set enable and clock divider */ + __raw_writel(div | CONTROL_ENABLE, &data->regs->control); + + /* + * One mdio transaction consists of: + * 32 bits of preamble + * 32 bits of transferred data + * 24 bits of bus yield (not needed unless shared?) + */ + mdio_out_khz = mdio_in / (1000 * (div + 1)); + access_time = (88 * 1000) / mdio_out_khz; + + /* + * In the worst case, we could be kicking off a user-access immediately + * after the mdio bus scan state-machine triggered its own read. If + * so, our request could get deferred by one access cycle. We + * defensively allow for 4 access cycles. + */ + data->access_time = usecs_to_jiffies(access_time * 4); + if (!data->access_time) + data->access_time = 1; +} + +static int davinci_mdio_reset(struct mii_bus *bus) +{ + struct davinci_mdio_data *data = bus->priv; + u32 phy_mask, ver; + + __davinci_mdio_reset(data); + + /* wait for scan logic to settle */ + msleep(PHY_MAX_ADDR * data->access_time); + + /* dump hardware version info */ + ver = __raw_readl(&data->regs->version); + dev_info(data->dev, "davinci mdio revision %d.%d\n", + (ver >> 8) & 0xff, ver & 0xff); + + /* get phy mask from the alive register */ + phy_mask = __raw_readl(&data->regs->alive); + if (phy_mask) { + /* restrict mdio bus to live phys only */ + dev_info(data->dev, "detected phy mask %x\n", ~phy_mask); + phy_mask = ~phy_mask; + } else { + /* desperately scan all phys */ + dev_warn(data->dev, "no live phy, scanning all\n"); + phy_mask = 0; + } + data->bus->phy_mask = phy_mask; + + return 0; +} + +/* wait until hardware is ready for another user access */ +static inline int wait_for_user_access(struct davinci_mdio_data *data) +{ + struct davinci_mdio_regs __iomem *regs = data->regs; + unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); + u32 reg; + + while (time_after(timeout, jiffies)) { + reg = __raw_readl(®s->user[0].access); + if ((reg & USERACCESS_GO) == 0) + return 0; + + reg = __raw_readl(®s->control); + if ((reg & CONTROL_IDLE) == 0) + continue; + + /* + * An emac soft_reset may have clobbered the mdio controller's + * state machine. We need to reset and retry the current + * operation + */ + dev_warn(data->dev, "resetting idled controller\n"); + __davinci_mdio_reset(data); + return -EAGAIN; + } + dev_err(data->dev, "timed out waiting for user access\n"); + return -ETIMEDOUT; +} + +/* wait until hardware state machine is idle */ +static inline int wait_for_idle(struct davinci_mdio_data *data) +{ + struct davinci_mdio_regs __iomem *regs = data->regs; + unsigned long timeout = jiffies + msecs_to_jiffies(MDIO_TIMEOUT); + + while (time_after(timeout, jiffies)) { + if (__raw_readl(®s->control) & CONTROL_IDLE) + return 0; + } + dev_err(data->dev, "timed out waiting for idle\n"); + return -ETIMEDOUT; +} + +static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg) +{ + struct davinci_mdio_data *data = bus->priv; + u32 reg; + int ret; + + if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) + return -EINVAL; + + spin_lock(&data->lock); + + if (data->suspended) { + spin_unlock(&data->lock); + return -ENODEV; + } + + reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) | + (phy_id << 16)); + + while (1) { + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + if (ret < 0) + break; + + __raw_writel(reg, &data->regs->user[0].access); + + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + if (ret < 0) + break; + + reg = __raw_readl(&data->regs->user[0].access); + ret = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -EIO; + break; + } + + spin_unlock(&data->lock); + + return ret; +} + +static int davinci_mdio_write(struct mii_bus *bus, int phy_id, + int phy_reg, u16 phy_data) +{ + struct davinci_mdio_data *data = bus->priv; + u32 reg; + int ret; + + if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK) + return -EINVAL; + + spin_lock(&data->lock); + + if (data->suspended) { + spin_unlock(&data->lock); + return -ENODEV; + } + + reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) | + (phy_id << 16) | (phy_data & USERACCESS_DATA)); + + while (1) { + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + if (ret < 0) + break; + + __raw_writel(reg, &data->regs->user[0].access); + + ret = wait_for_user_access(data); + if (ret == -EAGAIN) + continue; + break; + } + + spin_unlock(&data->lock); + + return 0; +} + +static int __devinit davinci_mdio_probe(struct platform_device *pdev) +{ + struct mdio_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct davinci_mdio_data *data; + struct resource *res; + struct phy_device *phy; + int ret, addr; + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + dev_err(dev, "failed to alloc device data\n"); + return -ENOMEM; + } + + data->pdata = pdata ? (*pdata) : default_pdata; + + data->bus = mdiobus_alloc(); + if (!data->bus) { + dev_err(dev, "failed to alloc mii bus\n"); + ret = -ENOMEM; + goto bail_out; + } + + data->bus->name = dev_name(dev); + data->bus->read = davinci_mdio_read, + data->bus->write = davinci_mdio_write, + data->bus->reset = davinci_mdio_reset, + data->bus->parent = dev; + data->bus->priv = data; + snprintf(data->bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); + + data->clk = clk_get(dev, NULL); + if (IS_ERR(data->clk)) { + data->clk = NULL; + dev_err(dev, "failed to get device clock\n"); + ret = PTR_ERR(data->clk); + goto bail_out; + } + + clk_enable(data->clk); + + dev_set_drvdata(dev, data); + data->dev = dev; + spin_lock_init(&data->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "could not find register map resource\n"); + ret = -ENOENT; + goto bail_out; + } + + res = devm_request_mem_region(dev, res->start, resource_size(res), + dev_name(dev)); + if (!res) { + dev_err(dev, "could not allocate register map resource\n"); + ret = -ENXIO; + goto bail_out; + } + + data->regs = devm_ioremap_nocache(dev, res->start, resource_size(res)); + if (!data->regs) { + dev_err(dev, "could not map mdio registers\n"); + ret = -ENOMEM; + goto bail_out; + } + + /* register the mii bus */ + ret = mdiobus_register(data->bus); + if (ret) + goto bail_out; + + /* scan and dump the bus */ + for (addr = 0; addr < PHY_MAX_ADDR; addr++) { + phy = data->bus->phy_map[addr]; + if (phy) { + dev_info(dev, "phy[%d]: device %s, driver %s\n", + phy->addr, dev_name(&phy->dev), + phy->drv ? phy->drv->name : "unknown"); + } + } + + return 0; + +bail_out: + if (data->bus) + mdiobus_free(data->bus); + + if (data->clk) { + clk_disable(data->clk); + clk_put(data->clk); + } + + kfree(data); + + return ret; +} + +static int __devexit davinci_mdio_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct davinci_mdio_data *data = dev_get_drvdata(dev); + + if (data->bus) + mdiobus_free(data->bus); + + if (data->clk) { + clk_disable(data->clk); + clk_put(data->clk); + } + + dev_set_drvdata(dev, NULL); + + kfree(data); + + return 0; +} + +static int davinci_mdio_suspend(struct device *dev) +{ + struct davinci_mdio_data *data = dev_get_drvdata(dev); + u32 ctrl; + + spin_lock(&data->lock); + + /* shutdown the scan state machine */ + ctrl = __raw_readl(&data->regs->control); + ctrl &= ~CONTROL_ENABLE; + __raw_writel(ctrl, &data->regs->control); + wait_for_idle(data); + + if (data->clk) + clk_disable(data->clk); + + data->suspended = true; + spin_unlock(&data->lock); + + return 0; +} + +static int davinci_mdio_resume(struct device *dev) +{ + struct davinci_mdio_data *data = dev_get_drvdata(dev); + u32 ctrl; + + spin_lock(&data->lock); + if (data->clk) + clk_enable(data->clk); + + /* restart the scan state machine */ + ctrl = __raw_readl(&data->regs->control); + ctrl |= CONTROL_ENABLE; + __raw_writel(ctrl, &data->regs->control); + + data->suspended = false; + spin_unlock(&data->lock); + + return 0; +} + +static const struct dev_pm_ops davinci_mdio_pm_ops = { + .suspend = davinci_mdio_suspend, + .resume = davinci_mdio_resume, +}; + +static struct platform_driver davinci_mdio_driver = { + .driver = { + .name = "davinci_mdio", + .owner = THIS_MODULE, + .pm = &davinci_mdio_pm_ops, + }, + .probe = davinci_mdio_probe, + .remove = __devexit_p(davinci_mdio_remove), +}; + +static int __init davinci_mdio_init(void) +{ + return platform_driver_register(&davinci_mdio_driver); +} +device_initcall(davinci_mdio_init); + +static void __exit davinci_mdio_exit(void) +{ + platform_driver_unregister(&davinci_mdio_driver); +} +module_exit(davinci_mdio_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("DaVinci MDIO driver"); diff --git a/include/linux/davinci_emac.h b/include/linux/davinci_emac.h index 7c930db..a04fd8c 100644 --- a/include/linux/davinci_emac.h +++ b/include/linux/davinci_emac.h @@ -14,6 +14,10 @@ #include #include +struct mdio_platform_data { + unsigned long bus_freq; +}; + struct emac_platform_data { char mac_addr[ETH_ALEN]; u32 ctrl_reg_offset; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:56 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:56 -0700 Subject: [PATCH 32/47] davinci: add mdio platform devices In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-33-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds mdio platform devices on SoCs that have the necessary hardware. Clock lookup entries (aliases) have also been added, so that the MDIO and EMAC drivers can independently enable/disable a shared underlying clock. Further, the EMAC MMR region has been split down into separate MDIO and EMAC regions. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices-da8xx.c | 29 +++++++++++++++++++++++++- arch/arm/mach-davinci/dm365.c | 22 +++++++++++++++++++- arch/arm/mach-davinci/dm644x.c | 22 +++++++++++++++++++- arch/arm/mach-davinci/dm646x.c | 21 ++++++++++++++++++- arch/arm/mach-davinci/include/mach/dm365.h | 1 + arch/arm/mach-davinci/include/mach/dm644x.h | 1 + arch/arm/mach-davinci/include/mach/dm646x.h | 1 + 7 files changed, 92 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index caeb7f4..9039221 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -352,7 +352,7 @@ int __init da8xx_register_watchdog(void) static struct resource da8xx_emac_resources[] = { { .start = DA8XX_EMAC_CPPI_PORT_BASE, - .end = DA8XX_EMAC_CPPI_PORT_BASE + 0x5000 - 1, + .end = DA8XX_EMAC_CPPI_PORT_BASE + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { @@ -396,9 +396,34 @@ static struct platform_device da8xx_emac_device = { .resource = da8xx_emac_resources, }; +static struct resource da8xx_mdio_resources[] = { + { + .start = DA8XX_EMAC_MDIO_BASE, + .end = DA8XX_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da8xx_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(da8xx_mdio_resources), + .resource = da8xx_mdio_resources, +}; + int __init da8xx_register_emac(void) { - return platform_device_register(&da8xx_emac_device); + int ret; + + ret = platform_device_register(&da8xx_mdio_device); + if (ret < 0) + return ret; + ret = platform_device_register(&da8xx_emac_device); + if (ret < 0) + return ret; + ret = clk_add_alias(NULL, dev_name(&da8xx_mdio_device.dev), + NULL, &da8xx_emac_device.dev); + return ret; } static struct resource da830_mcasp1_resources[] = { diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 6b6f4c6..71f0f9d 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -699,7 +699,7 @@ static struct emac_platform_data dm365_emac_pdata = { static struct resource dm365_emac_resources[] = { { .start = DM365_EMAC_BASE, - .end = DM365_EMAC_BASE + 0x47ff, + .end = DM365_EMAC_BASE + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { @@ -734,6 +734,21 @@ static struct platform_device dm365_emac_device = { .resource = dm365_emac_resources, }; +static struct resource dm365_mdio_resources[] = { + { + .start = DM365_EMAC_MDIO_BASE, + .end = DM365_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm365_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm365_mdio_resources), + .resource = dm365_mdio_resources, +}; + static u8 dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = { [IRQ_VDINT0] = 2, [IRQ_VDINT1] = 6, @@ -1220,7 +1235,12 @@ static int __init dm365_init_devices(void) davinci_cfg_reg(DM365_INT_EDMA_CC); platform_device_register(&dm365_edma_device); + + platform_device_register(&dm365_mdio_device); platform_device_register(&dm365_emac_device); + clk_add_alias(NULL, dev_name(&dm365_mdio_device.dev), + NULL, &dm365_emac_device.dev); + /* Add isif clock alias */ clk_add_alias("master", dm365_isif_dev.name, "vpss_master", NULL); platform_device_register(&dm365_vpss_device); diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 40fec31..c103b2c 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -330,7 +330,7 @@ static struct emac_platform_data dm644x_emac_pdata = { static struct resource dm644x_emac_resources[] = { { .start = DM644X_EMAC_BASE, - .end = DM644X_EMAC_BASE + 0x47ff, + .end = DM644X_EMAC_BASE + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { @@ -350,6 +350,21 @@ static struct platform_device dm644x_emac_device = { .resource = dm644x_emac_resources, }; +static struct resource dm644x_mdio_resources[] = { + { + .start = DM644X_EMAC_MDIO_BASE, + .end = DM644X_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm644x_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm644x_mdio_resources), + .resource = dm644x_mdio_resources, +}; + /* * Device specific mux setup * @@ -777,7 +792,12 @@ static int __init dm644x_init_devices(void) clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL); clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL); platform_device_register(&dm644x_edma_device); + + platform_device_register(&dm644x_mdio_device); platform_device_register(&dm644x_emac_device); + clk_add_alias(NULL, dev_name(&dm644x_mdio_device.dev), + NULL, &dm644x_emac_device.dev); + platform_device_register(&dm644x_vpss_device); platform_device_register(&dm644x_ccdc_dev); platform_device_register(&vpfe_capture_dev); diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e4a3df1..8da886b 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -366,7 +366,7 @@ static struct emac_platform_data dm646x_emac_pdata = { static struct resource dm646x_emac_resources[] = { { .start = DM646X_EMAC_BASE, - .end = DM646X_EMAC_BASE + 0x47ff, + .end = DM646X_EMAC_BASE + SZ_16K - 1, .flags = IORESOURCE_MEM, }, { @@ -401,6 +401,21 @@ static struct platform_device dm646x_emac_device = { .resource = dm646x_emac_resources, }; +static struct resource dm646x_mdio_resources[] = { + { + .start = DM646X_EMAC_MDIO_BASE, + .end = DM646X_EMAC_MDIO_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device dm646x_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(dm646x_mdio_resources), + .resource = dm646x_mdio_resources, +}; + /* * Device specific mux setup * @@ -897,7 +912,11 @@ static int __init dm646x_init_devices(void) if (!cpu_is_davinci_dm646x()) return 0; + platform_device_register(&dm646x_mdio_device); platform_device_register(&dm646x_emac_device); + clk_add_alias(NULL, dev_name(&dm646x_mdio_device.dev), + NULL, &dm646x_emac_device.dev); + return 0; } postcore_initcall(dm646x_init_devices); diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h index ea5df3b..dbb5052 100644 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ b/arch/arm/mach-davinci/include/mach/dm365.h @@ -21,6 +21,7 @@ #include #define DM365_EMAC_BASE (0x01D07000) +#define DM365_EMAC_MDIO_BASE (DM365_EMAC_BASE + 0x4000) #define DM365_EMAC_CNTRL_OFFSET (0x0000) #define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000) #define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000) diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 6fca568..5159117 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -28,6 +28,7 @@ #include #define DM644X_EMAC_BASE (0x01C80000) +#define DM644X_EMAC_MDIO_BASE (DM644X_EMAC_BASE + 0x4000) #define DM644X_EMAC_CNTRL_OFFSET (0x0000) #define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000) #define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000) diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 0a27ee9..1c4dca9 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -19,6 +19,7 @@ #include #define DM646X_EMAC_BASE (0x01C80000) +#define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) #define DM646X_EMAC_CNTRL_OFFSET (0x0000) #define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000) #define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000) -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:57 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:57 -0700 Subject: [PATCH 33/47] omap: add mdio platform devices In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-34-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds mdio platform devices on SoCs that have the necessary hardware. Clock lookup entries (aliases) have also been added, so that the MDIO and EMAC drivers can independently enable/disable a shared underlying clock. Further, the EMAC MMR region has been split down into separate MDIO and EMAC regions. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Acked-by: Tony Lindgren Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-am3517evm.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 4d0f585..5dd1b73 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,27 @@ #define AM35XX_EVM_PHY_MASK (0xF) #define AM35XX_EVM_MDIO_FREQUENCY (1000000) +static struct mdio_platform_data am3517_evm_mdio_pdata = { + .bus_freq = AM35XX_EVM_MDIO_FREQUENCY, +}; + +static struct resource am3517_mdio_resources[] = { + { + .start = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET, + .end = AM35XX_IPSS_EMAC_BASE + AM35XX_EMAC_MDIO_OFFSET + + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device am3517_mdio_device = { + .name = "davinci_mdio", + .id = 0, + .num_resources = ARRAY_SIZE(am3517_mdio_resources), + .resource = am3517_mdio_resources, + .dev.platform_data = &am3517_evm_mdio_pdata, +}; + static struct emac_platform_data am3517_evm_emac_pdata = { .phy_mask = AM35XX_EVM_PHY_MASK, .mdio_max_freq = AM35XX_EVM_MDIO_FREQUENCY, @@ -50,7 +72,7 @@ static struct emac_platform_data am3517_evm_emac_pdata = { static struct resource am3517_emac_resources[] = { { .start = AM35XX_IPSS_EMAC_BASE, - .end = AM35XX_IPSS_EMAC_BASE + 0x3FFFF, + .end = AM35XX_IPSS_EMAC_BASE + 0x2FFFF, .flags = IORESOURCE_MEM, }, { @@ -121,6 +143,9 @@ void am3517_evm_ethernet_init(struct emac_platform_data *pdata) pdata->interrupt_disable = am3517_disable_ethernet_int; am3517_emac_device.dev.platform_data = pdata; platform_device_register(&am3517_emac_device); + platform_device_register(&am3517_mdio_device); + clk_add_alias(NULL, dev_name(&am3517_mdio_device.dev), + NULL, &am3517_emac_device.dev); regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); regval = regval & (~(AM35XX_CPGMACSS_SW_RST)); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:58 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:58 -0700 Subject: [PATCH 34/47] net: davinci_emac: switch to new mdio In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-35-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch switches the emac implementation over to the newly separated MDIO driver. With this, the mdio bus frequency defaults to a safe 2.2MHz. Boards may optionally specify a bus frequency via platform data. The phy identification scheme has been modified to use a phy bus id instead of a mask. This largely serves to eliminate the "phy search" code in emac init. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/Kconfig | 1 + drivers/net/davinci_emac.c | 88 ++++++++++++++--------------------------- include/linux/davinci_emac.h | 9 ++++ 3 files changed, 40 insertions(+), 58 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c5c86e0..911e7f1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -951,6 +951,7 @@ config NET_NETX config TI_DAVINCI_EMAC tristate "TI DaVinci EMAC Support" depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) + select TI_DAVINCI_MDIO select PHYLIB help This driver supports TI's DaVinci Ethernet . diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 7fbd052..997f599 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -500,6 +500,7 @@ struct emac_priv { u32 phy_mask; /* mii_bus,phy members */ struct mii_bus *mii_bus; + const char *phy_id; struct phy_device *phydev; spinlock_t lock; /*platform specific members*/ @@ -686,7 +687,7 @@ static int emac_get_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct emac_priv *priv = netdev_priv(ndev); - if (priv->phy_mask) + if (priv->phydev) return phy_ethtool_gset(priv->phydev, ecmd); else return -EOPNOTSUPP; @@ -704,7 +705,7 @@ static int emac_get_settings(struct net_device *ndev, static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd) { struct emac_priv *priv = netdev_priv(ndev); - if (priv->phy_mask) + if (priv->phydev) return phy_ethtool_sset(priv->phydev, ecmd); else return -EOPNOTSUPP; @@ -841,7 +842,7 @@ static void emac_update_phystatus(struct emac_priv *priv) mac_control = emac_read(EMAC_MACCONTROL); cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ? DUPLEX_FULL : DUPLEX_HALF; - if (priv->phy_mask) + if (priv->phydev) new_duplex = priv->phydev->duplex; else new_duplex = DUPLEX_FULL; @@ -2485,6 +2486,11 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) return -EOPNOTSUPP; } +static int match_first_device(struct device *dev, void *data) +{ + return 1; +} + /** * emac_dev_open: EMAC device open * @ndev: The DaVinci EMAC network adapter @@ -2499,7 +2505,6 @@ static int emac_dev_open(struct net_device *ndev) { struct device *emac_dev = &ndev->dev; u32 rc, cnt, ch; - int phy_addr; struct resource *res; int q, m; int i = 0; @@ -2560,28 +2565,26 @@ static int emac_dev_open(struct net_device *ndev) emac_set_coalesce(ndev, &coal); } - /* find the first phy */ priv->phydev = NULL; - if (priv->phy_mask) { - emac_mii_reset(priv->mii_bus); - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { - if (priv->mii_bus->phy_map[phy_addr]) { - priv->phydev = priv->mii_bus->phy_map[phy_addr]; - break; - } - } + /* use the first phy on the bus if pdata did not give us a phy id */ + if (!priv->phy_id) { + struct device *phy; - if (!priv->phydev) { - printk(KERN_ERR "%s: no PHY found\n", ndev->name); - return -1; - } + phy = bus_find_device(&mdio_bus_type, NULL, NULL, + match_first_device); + if (phy) + priv->phy_id = dev_name(phy); + } - priv->phydev = phy_connect(ndev, dev_name(&priv->phydev->dev), - &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII); + if (priv->phy_id && *priv->phy_id) { + priv->phydev = phy_connect(ndev, priv->phy_id, + &emac_adjust_link, 0, + PHY_INTERFACE_MODE_MII); if (IS_ERR(priv->phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", - ndev->name); + dev_err(emac_dev, "could not connect to phy %s\n", + priv->phy_id); + priv->phydev = NULL; return PTR_ERR(priv->phydev); } @@ -2589,12 +2592,13 @@ static int emac_dev_open(struct net_device *ndev) priv->speed = 0; priv->duplex = ~0; - printk(KERN_INFO "%s: attached PHY driver [%s] " - "(mii_bus:phy_addr=%s, id=%x)\n", ndev->name, + dev_info(emac_dev, "attached PHY driver [%s] " + "(mii_bus:phy_addr=%s, id=%x)\n", priv->phydev->drv->name, dev_name(&priv->phydev->dev), priv->phydev->phy_id); - } else{ + } else { /* No PHY , fix the link, speed and duplex settings */ + dev_notice(emac_dev, "no phy, defaulting to 100/full\n"); priv->link = 1; priv->speed = SPEED_100; priv->duplex = DUPLEX_FULL; @@ -2607,7 +2611,7 @@ static int emac_dev_open(struct net_device *ndev) if (netif_msg_drv(priv)) dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name); - if (priv->phy_mask) + if (priv->phydev) phy_start(priv->phydev); return 0; @@ -2794,7 +2798,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) /* MAC addr and PHY mask , RMII enable info from platform_data */ memcpy(priv->mac_addr, pdata->mac_addr, 6); - priv->phy_mask = pdata->phy_mask; + priv->phy_id = pdata->phy_id; priv->rmii_en = pdata->rmii_en; priv->version = pdata->version; priv->int_enable = pdata->interrupt_enable; @@ -2871,32 +2875,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) } - /* MII/Phy intialisation, mdio bus registration */ - emac_mii = mdiobus_alloc(); - if (emac_mii == NULL) { - dev_err(emac_dev, "DaVinci EMAC: Error allocating mii_bus\n"); - rc = -ENOMEM; - goto mdio_alloc_err; - } - - priv->mii_bus = emac_mii; - emac_mii->name = "emac-mii", - emac_mii->read = emac_mii_read, - emac_mii->write = emac_mii_write, - emac_mii->reset = emac_mii_reset, - emac_mii->irq = mii_irqs, - emac_mii->phy_mask = ~(priv->phy_mask); - emac_mii->parent = &pdev->dev; - emac_mii->priv = priv->remap_addr + pdata->mdio_reg_offset; - snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", priv->pdev->id); - mdio_max_freq = pdata->mdio_max_freq; - emac_mii->reset(emac_mii); - - /* Register the MII bus */ - rc = mdiobus_register(emac_mii); - if (rc) - goto mdiobus_quit; - if (netif_msg_probe(priv)) { dev_notice(emac_dev, "DaVinci EMAC Probe found device "\ "(regs: %p, irq: %d)\n", @@ -2904,11 +2882,7 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) } return 0; -mdiobus_quit: - mdiobus_free(emac_mii); - netdev_reg_err: -mdio_alloc_err: clk_disable(emac_clk); no_irq_res: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2938,8 +2912,6 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mdiobus_unregister(priv->mii_bus); - mdiobus_free(priv->mii_bus); release_mem_region(res->start, res->end - res->start + 1); diff --git a/include/linux/davinci_emac.h b/include/linux/davinci_emac.h index a04fd8c..46a759f 100644 --- a/include/linux/davinci_emac.h +++ b/include/linux/davinci_emac.h @@ -28,6 +28,15 @@ struct emac_platform_data { u32 ctrl_ram_size; u32 phy_mask; u32 mdio_max_freq; + + /* + * phy_id can be one of the following: + * - NULL : use the first phy on the bus, + * - "" : force to 100/full, no mdio control + * - ":" : use the specified bus and phy + */ + const char *phy_id; + u8 rmii_en; u8 version; void (*interrupt_enable) (void); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:29:59 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:29:59 -0700 Subject: [PATCH 35/47] davinci: cleanup mdio arch code and switch to phy_id In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-36-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch removes davinci architecture code that has now been rendered useless by the previous patches in the MDIO separation series. In addition, the earlier phy_mask definitions have been replaced with corresponding phy_id definitions. Signed-off-by: Cyril Chemparathy Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-da830-evm.c | 7 ++----- arch/arm/mach-davinci/board-da850-evm.c | 7 ++----- arch/arm/mach-davinci/board-dm365-evm.c | 7 ++----- arch/arm/mach-davinci/board-dm644x-evm.c | 8 ++------ arch/arm/mach-davinci/board-dm646x-evm.c | 7 ++----- arch/arm/mach-davinci/board-mityomapl138.c | 8 ++------ arch/arm/mach-davinci/board-neuros-osd2.c | 7 ++----- arch/arm/mach-davinci/board-sffsdr.c | 7 ++----- arch/arm/mach-davinci/devices-da8xx.c | 2 -- arch/arm/mach-davinci/dm365.c | 1 - arch/arm/mach-davinci/dm644x.c | 1 - arch/arm/mach-davinci/dm646x.c | 1 - arch/arm/mach-davinci/include/mach/dm365.h | 1 - arch/arm/mach-davinci/include/mach/dm644x.h | 1 - arch/arm/mach-davinci/include/mach/dm646x.h | 1 - 15 files changed, 16 insertions(+), 50 deletions(-) diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index ef1ab0b..1bb89d3 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -31,9 +31,7 @@ #include #include -#define DA830_EVM_PHY_MASK 0x0 -#define DA830_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ - +#define DA830_EVM_PHY_ID "" /* * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4]. */ @@ -558,9 +556,8 @@ static __init void da830_evm_init(void) da830_evm_usb_init(); - soc_info->emac_pdata->phy_mask = DA830_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DA830_EVM_MDIO_FREQUENCY; soc_info->emac_pdata->rmii_en = 1; + soc_info->emac_pdata->phy_id = DA830_EVM_PHY_ID; ret = davinci_cfg_reg_list(da830_cpgmac_pins); if (ret) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index ac2297c..5e435b0 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -38,9 +38,7 @@ #include #include -#define DA850_EVM_PHY_MASK 0x1 -#define DA850_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ - +#define DA850_EVM_PHY_ID "0:00" #define DA850_LCD_PWR_PIN GPIO_TO_PIN(2, 8) #define DA850_LCD_BL_PIN GPIO_TO_PIN(2, 15) @@ -678,8 +676,7 @@ static int __init da850_evm_config_emac(void) /* Enable/Disable MII MDIO clock */ gpio_direction_output(DA850_MII_MDIO_CLKEN_PIN, rmii_en); - soc_info->emac_pdata->phy_mask = DA850_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DA850_EVM_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; ret = da8xx_register_emac(); if (ret) diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index bdea2da..a06b84c 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -54,9 +54,7 @@ static inline int have_tvp7002(void) return 0; } -#define DM365_EVM_PHY_MASK (0x2) -#define DM365_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ - +#define DM365_EVM_PHY_ID "0:01" /* * A MAX-II CPLD is used for various board control functions. */ @@ -535,8 +533,7 @@ fail: /* ... and ENET ... */ dm365evm_emac_configure(); - soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = DM365_EVM_PHY_ID; resets &= ~BIT(3); /* ... and AIC33 */ diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 65bb940..44a2f0a 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -39,9 +39,7 @@ #include #include -#define DM644X_EVM_PHY_MASK (0x2) -#define DM644X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ - +#define DM644X_EVM_PHY_ID "0:01" #define LXT971_PHY_ID (0x001378e2) #define LXT971_PHY_MASK (0xfffffff0) @@ -707,9 +705,7 @@ static __init void davinci_evm_init(void) davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_evm_snd_data); - soc_info->emac_pdata->phy_mask = DM644X_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DM644X_EVM_MDIO_FREQUENCY; - + soc_info->emac_pdata->phy_id = DM644X_EVM_PHY_ID; /* Register the fixup for PHY on DaVinci */ phy_register_fixup_for_uid(LXT971_PHY_ID, LXT971_PHY_MASK, davinci_phy_fixup); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index 5a29955..67669bb 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -729,9 +729,7 @@ static struct davinci_uart_config uart_config __initdata = { .enabled_uarts = (1 << 0), }; -#define DM646X_EVM_PHY_MASK (0x2) -#define DM646X_EVM_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ - +#define DM646X_EVM_PHY_ID "0:01" /* * The following EDMA channels/slots are not being used by drivers (for * example: Timer, GPIO, UART events etc) on dm646x, hence they are being @@ -784,8 +782,7 @@ static __init void evm_init(void) if (HAS_ATA) davinci_init_ide(); - soc_info->emac_pdata->phy_mask = DM646X_EVM_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = DM646X_EVM_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = DM646X_EVM_PHY_ID; } #define DM646X_EVM_REF_FREQ 27000000 diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 84d5aff..6f12a18 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -24,9 +24,7 @@ #include #include -#define MITYOMAPL138_PHY_MASK 0x08 /* hardcoded for now */ -#define MITYOMAPL138_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ - +#define MITYOMAPL138_PHY_ID "0:03" static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { .bus_freq = 100, /* kHz */ .bus_delay = 0, /* usec */ @@ -273,9 +271,7 @@ static void __init mityomapl138_config_emac(void) /* configure the CFGCHIP3 register for RMII or MII */ __raw_writel(val, cfg_chip3_base); - soc_info->emac_pdata->phy_mask = MITYOMAPL138_PHY_MASK; - pr_debug("setting phy_mask to %x\n", soc_info->emac_pdata->phy_mask); - soc_info->emac_pdata->mdio_max_freq = MITYOMAPL138_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = MITYOMAPL138_PHY_ID; ret = da8xx_register_emac(); if (ret) diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 4c30e92..04a8d16 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -39,9 +39,7 @@ #include #include -#define NEUROS_OSD2_PHY_MASK 0x2 -#define NEUROS_OSD2_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ - +#define NEUROS_OSD2_PHY_ID "0:01" #define LXT971_PHY_ID 0x001378e2 #define LXT971_PHY_MASK 0xfffffff0 @@ -252,8 +250,7 @@ static __init void davinci_ntosd2_init(void) davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_ntosd2_snd_data); - soc_info->emac_pdata->phy_mask = NEUROS_OSD2_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = NEUROS_OSD2_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = NEUROS_OSD2_PHY_ID; davinci_setup_usb(1000, 8); /* diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index 23e664a..ab4292d 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -42,9 +42,7 @@ #include #include -#define SFFSDR_PHY_MASK (0x2) -#define SFFSDR_MDIO_FREQUENCY (2200000) /* PHY bus frequency */ - +#define SFFSDR_PHY_ID "0:01" static struct mtd_partition davinci_sffsdr_nandflash_partition[] = { /* U-Boot Environment: Block 0 * UBL: Block 1 @@ -143,8 +141,7 @@ static __init void davinci_sffsdr_init(void) ARRAY_SIZE(davinci_sffsdr_devices)); sffsdr_init_i2c(); davinci_serial_init(&uart_config); - soc_info->emac_pdata->phy_mask = SFFSDR_PHY_MASK; - soc_info->emac_pdata->mdio_max_freq = SFFSDR_MDIO_FREQUENCY; + soc_info->emac_pdata->phy_id = SFFSDR_PHY_ID; davinci_setup_usb(0, 0); /* We support only peripheral mode. */ /* mux VLYNQ pins */ diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 9039221..9eec630 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -42,7 +42,6 @@ #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 #define DA8XX_EMAC_RAM_OFFSET 0x0000 -#define DA8XX_MDIO_REG_OFFSET 0x4000 #define DA8XX_EMAC_CTRL_RAM_SIZE SZ_8K void __iomem *da8xx_syscfg0_base; @@ -381,7 +380,6 @@ struct emac_platform_data da8xx_emac_pdata = { .ctrl_reg_offset = DA8XX_EMAC_CTRL_REG_OFFSET, .ctrl_mod_reg_offset = DA8XX_EMAC_MOD_REG_OFFSET, .ctrl_ram_offset = DA8XX_EMAC_RAM_OFFSET, - .mdio_reg_offset = DA8XX_MDIO_REG_OFFSET, .ctrl_ram_size = DA8XX_EMAC_CTRL_RAM_SIZE, .version = EMAC_VERSION_2, }; diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 71f0f9d..240f392 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -691,7 +691,6 @@ static struct emac_platform_data dm365_emac_pdata = { .ctrl_reg_offset = DM365_EMAC_CNTRL_OFFSET, .ctrl_mod_reg_offset = DM365_EMAC_CNTRL_MOD_OFFSET, .ctrl_ram_offset = DM365_EMAC_CNTRL_RAM_OFFSET, - .mdio_reg_offset = DM365_EMAC_MDIO_OFFSET, .ctrl_ram_size = DM365_EMAC_CNTRL_RAM_SIZE, .version = EMAC_VERSION_2, }; diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index c103b2c..41b7a95 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -322,7 +322,6 @@ static struct emac_platform_data dm644x_emac_pdata = { .ctrl_reg_offset = DM644X_EMAC_CNTRL_OFFSET, .ctrl_mod_reg_offset = DM644X_EMAC_CNTRL_MOD_OFFSET, .ctrl_ram_offset = DM644X_EMAC_CNTRL_RAM_OFFSET, - .mdio_reg_offset = DM644X_EMAC_MDIO_OFFSET, .ctrl_ram_size = DM644X_EMAC_CNTRL_RAM_SIZE, .version = EMAC_VERSION_1, }; diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 8da886b..08db90f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -358,7 +358,6 @@ static struct emac_platform_data dm646x_emac_pdata = { .ctrl_reg_offset = DM646X_EMAC_CNTRL_OFFSET, .ctrl_mod_reg_offset = DM646X_EMAC_CNTRL_MOD_OFFSET, .ctrl_ram_offset = DM646X_EMAC_CNTRL_RAM_OFFSET, - .mdio_reg_offset = DM646X_EMAC_MDIO_OFFSET, .ctrl_ram_size = DM646X_EMAC_CNTRL_RAM_SIZE, .version = EMAC_VERSION_2, }; diff --git a/arch/arm/mach-davinci/include/mach/dm365.h b/arch/arm/mach-davinci/include/mach/dm365.h index dbb5052..2563bf4 100644 --- a/arch/arm/mach-davinci/include/mach/dm365.h +++ b/arch/arm/mach-davinci/include/mach/dm365.h @@ -25,7 +25,6 @@ #define DM365_EMAC_CNTRL_OFFSET (0x0000) #define DM365_EMAC_CNTRL_MOD_OFFSET (0x3000) #define DM365_EMAC_CNTRL_RAM_OFFSET (0x1000) -#define DM365_EMAC_MDIO_OFFSET (0x4000) #define DM365_EMAC_CNTRL_RAM_SIZE (0x2000) /* Base of key scan register bank */ diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 5159117..5a1b26d 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -32,7 +32,6 @@ #define DM644X_EMAC_CNTRL_OFFSET (0x0000) #define DM644X_EMAC_CNTRL_MOD_OFFSET (0x1000) #define DM644X_EMAC_CNTRL_RAM_OFFSET (0x2000) -#define DM644X_EMAC_MDIO_OFFSET (0x4000) #define DM644X_EMAC_CNTRL_RAM_SIZE (0x2000) #define DM644X_ASYNC_EMIF_CONTROL_BASE 0x01E00000 diff --git a/arch/arm/mach-davinci/include/mach/dm646x.h b/arch/arm/mach-davinci/include/mach/dm646x.h index 1c4dca9..7a27f3f 100644 --- a/arch/arm/mach-davinci/include/mach/dm646x.h +++ b/arch/arm/mach-davinci/include/mach/dm646x.h @@ -23,7 +23,6 @@ #define DM646X_EMAC_CNTRL_OFFSET (0x0000) #define DM646X_EMAC_CNTRL_MOD_OFFSET (0x1000) #define DM646X_EMAC_CNTRL_RAM_OFFSET (0x2000) -#define DM646X_EMAC_MDIO_OFFSET (0x4000) #define DM646X_EMAC_CNTRL_RAM_SIZE (0x2000) #define DM646X_ASYNC_EMIF_CONTROL_BASE 0x20008000 -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:01 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:01 -0700 Subject: [PATCH 37/47] net: davinci_emac: cleanup unused mdio emac code In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-38-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch removes code that has been rendered useless by the previous patches in this series. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/davinci_emac.c | 107 ------------------------------------------ include/linux/davinci_emac.h | 3 - 2 files changed, 0 insertions(+), 110 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 997f599..d4298cb 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -113,7 +113,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DEF_MAX_FRAME_SIZE (1500 + 14 + 4 + 4) #define EMAC_DEF_TX_CH (0) /* Default 0th channel */ #define EMAC_DEF_RX_CH (0) /* Default 0th channel */ -#define EMAC_DEF_MDIO_TICK_MS (10) /* typically 1 tick=1 ms) */ #define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */ #define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */ #define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */ @@ -303,25 +302,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DM644X_INTMIN_INTVL 0x1 #define EMAC_DM644X_INTMAX_INTVL (EMAC_DM644X_EWINTCNT_MASK) -/* EMAC MDIO related */ -/* Mask & Control defines */ -#define MDIO_CONTROL_CLKDIV (0xFF) -#define MDIO_CONTROL_ENABLE BIT(30) -#define MDIO_USERACCESS_GO BIT(31) -#define MDIO_USERACCESS_WRITE BIT(30) -#define MDIO_USERACCESS_READ (0) -#define MDIO_USERACCESS_REGADR (0x1F << 21) -#define MDIO_USERACCESS_PHYADR (0x1F << 16) -#define MDIO_USERACCESS_DATA (0xFFFF) -#define MDIO_USERPHYSEL_LINKSEL BIT(7) -#define MDIO_VER_MODID (0xFFFF << 16) -#define MDIO_VER_REVMAJ (0xFF << 8) -#define MDIO_VER_REVMIN (0xFF) - -#define MDIO_USERACCESS(inst) (0x80 + (inst * 8)) -#define MDIO_USERPHYSEL(inst) (0x84 + (inst * 8)) -#define MDIO_CONTROL (0x04) - /* EMAC DM646X control module registers */ #define EMAC_DM646X_CMINTCTRL 0x0C #define EMAC_DM646X_CMRXINTEN 0x14 @@ -493,13 +473,6 @@ struct emac_priv { u32 mac_hash2; u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; u32 rx_addr_type; - /* periodic timer required for MDIO polling */ - struct timer_list periodic_timer; - u32 periodic_ticks; - u32 timer_active; - u32 phy_mask; - /* mii_bus,phy members */ - struct mii_bus *mii_bus; const char *phy_id; struct phy_device *phydev; spinlock_t lock; @@ -511,7 +484,6 @@ struct emac_priv { /* clock frequency for EMAC */ static struct clk *emac_clk; static unsigned long emac_bus_frequency; -static unsigned long mdio_max_freq; #define emac_virt_to_phys(addr, priv) \ (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \ @@ -549,9 +521,6 @@ static char *emac_rxhost_errcodes[16] = { #define emac_ctrl_read(reg) ioread32((priv->ctrl_base + (reg))) #define emac_ctrl_write(reg, val) iowrite32(val, (priv->ctrl_base + (reg))) -#define emac_mdio_read(reg) ioread32(bus->priv + (reg)) -#define emac_mdio_write(reg, val) iowrite32(val, (bus->priv + (reg))) - /** * emac_dump_regs: Dump important EMAC registers to debug terminal * @priv: The DaVinci EMAC private adapter structure @@ -657,9 +626,6 @@ static void emac_dump_regs(struct emac_priv *priv) emac_read(EMAC_RXDMAOVERRUNS)); } -/************************************************************************* - * EMAC MDIO/Phy Functionality - *************************************************************************/ /** * emac_get_drvinfo: Get EMAC driver information * @ndev: The DaVinci EMAC network adapter @@ -2349,79 +2315,6 @@ void emac_poll_controller(struct net_device *ndev) } #endif -/* PHY/MII bus related */ - -/* Wait until mdio is ready for next command */ -#define MDIO_WAIT_FOR_USER_ACCESS\ - while ((emac_mdio_read((MDIO_USERACCESS(0))) &\ - MDIO_USERACCESS_GO) != 0) - -static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg) -{ - unsigned int phy_data = 0; - unsigned int phy_control; - - /* Wait until mdio is ready for next command */ - MDIO_WAIT_FOR_USER_ACCESS; - - phy_control = (MDIO_USERACCESS_GO | - MDIO_USERACCESS_READ | - ((phy_reg << 21) & MDIO_USERACCESS_REGADR) | - ((phy_id << 16) & MDIO_USERACCESS_PHYADR) | - (phy_data & MDIO_USERACCESS_DATA)); - emac_mdio_write(MDIO_USERACCESS(0), phy_control); - - /* Wait until mdio is ready for next command */ - MDIO_WAIT_FOR_USER_ACCESS; - - return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA; - -} - -static int emac_mii_write(struct mii_bus *bus, int phy_id, - int phy_reg, u16 phy_data) -{ - - unsigned int control; - - /* until mdio is ready for next command */ - MDIO_WAIT_FOR_USER_ACCESS; - - control = (MDIO_USERACCESS_GO | - MDIO_USERACCESS_WRITE | - ((phy_reg << 21) & MDIO_USERACCESS_REGADR) | - ((phy_id << 16) & MDIO_USERACCESS_PHYADR) | - (phy_data & MDIO_USERACCESS_DATA)); - emac_mdio_write(MDIO_USERACCESS(0), control); - - return 0; -} - -static int emac_mii_reset(struct mii_bus *bus) -{ - unsigned int clk_div; - int mdio_bus_freq = emac_bus_frequency; - - if (mdio_max_freq && mdio_bus_freq) - clk_div = ((mdio_bus_freq / mdio_max_freq) - 1); - else - clk_div = 0xFF; - - clk_div &= MDIO_CONTROL_CLKDIV; - - /* Set enable and clock divider in MDIOControl */ - emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE)); - - return 0; - -} - -static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, PHY_POLL }; - -/* emac_driver: EMAC MII bus structure */ - -static struct mii_bus *emac_mii; - static void emac_adjust_link(struct net_device *ndev) { struct emac_priv *priv = netdev_priv(ndev); diff --git a/include/linux/davinci_emac.h b/include/linux/davinci_emac.h index 46a759f..5dd4285 100644 --- a/include/linux/davinci_emac.h +++ b/include/linux/davinci_emac.h @@ -24,10 +24,7 @@ struct emac_platform_data { u32 ctrl_mod_reg_offset; u32 ctrl_ram_offset; u32 hw_ram_addr; - u32 mdio_reg_offset; u32 ctrl_ram_size; - u32 phy_mask; - u32 mdio_max_freq; /* * phy_id can be one of the following: -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:00 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:00 -0700 Subject: [PATCH 36/47] omap: cleanup unused davinci mdio arch code In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-37-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch removes davinci architecture code that has now been rendered useless by the previous patches in the MDIO separation series. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Acked-by: Tony Lindgren Signed-off-by: Kevin Hilman --- arch/arm/mach-omap2/board-am3517evm.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c index 5dd1b73..5225df6 100644 --- a/arch/arm/mach-omap2/board-am3517evm.c +++ b/arch/arm/mach-omap2/board-am3517evm.c @@ -39,7 +39,6 @@ #include "mux.h" -#define AM35XX_EVM_PHY_MASK (0xF) #define AM35XX_EVM_MDIO_FREQUENCY (1000000) static struct mdio_platform_data am3517_evm_mdio_pdata = { @@ -64,8 +63,6 @@ static struct platform_device am3517_mdio_device = { }; static struct emac_platform_data am3517_evm_emac_pdata = { - .phy_mask = AM35XX_EVM_PHY_MASK, - .mdio_max_freq = AM35XX_EVM_MDIO_FREQUENCY, .rmii_en = 1, }; @@ -135,7 +132,6 @@ void am3517_evm_ethernet_init(struct emac_platform_data *pdata) pdata->ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET; pdata->ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET; pdata->ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET; - pdata->mdio_reg_offset = AM35XX_EMAC_MDIO_OFFSET; pdata->ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE; pdata->version = EMAC_VERSION_2; pdata->hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:02 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:02 -0700 Subject: [PATCH 38/47] net: davinci_emac: separate out cpdma code In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-39-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy In addition to being embedded into the EMAC controller, the CPDMA hardware block is used in TI's CPSW switch controller. Fortunately, the programming interface to this hardware block remains pretty nicely consistent across these devices. This patch adds a new CPDMA services layer, which can then be reused across EMAC and CPSW drivers. Signed-off-by: Cyril Chemparathy Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/Kconfig | 10 + drivers/net/Makefile | 1 + drivers/net/davinci_cpdma.c | 965 +++++++++++++++++++++++++++++++++++++++++++ drivers/net/davinci_cpdma.h | 108 +++++ 4 files changed, 1084 insertions(+), 0 deletions(-) create mode 100644 drivers/net/davinci_cpdma.c create mode 100644 drivers/net/davinci_cpdma.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 911e7f1..775fd87 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -952,6 +952,7 @@ config TI_DAVINCI_EMAC tristate "TI DaVinci EMAC Support" depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) select TI_DAVINCI_MDIO + select TI_DAVINCI_CPDMA select PHYLIB help This driver supports TI's DaVinci Ethernet . @@ -969,6 +970,15 @@ config TI_DAVINCI_MDIO To compile this driver as a module, choose M here: the module will be called davinci_mdio. This is recommended. +config TI_DAVINCI_CPDMA + tristate "TI DaVinci CPDMA Support" + depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 ) + help + This driver supports TI's DaVinci CPDMA dma engine. + + To compile this driver as a module, choose M here: the module + will be called davinci_cpdma. This is recommended. + config DM9000 tristate "DM9000 support" depends on ARM || BLACKFIN || MIPS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index d38a7ab..65da885a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o +obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o obj-$(CONFIG_E1000) += e1000/ obj-$(CONFIG_E1000E) += e1000e/ diff --git a/drivers/net/davinci_cpdma.c b/drivers/net/davinci_cpdma.c new file mode 100644 index 0000000..e92b2b6 --- /dev/null +++ b/drivers/net/davinci_cpdma.c @@ -0,0 +1,965 @@ +/* + * Texas Instruments CPDMA Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "davinci_cpdma.h" + +/* DMA Registers */ +#define CPDMA_TXIDVER 0x00 +#define CPDMA_TXCONTROL 0x04 +#define CPDMA_TXTEARDOWN 0x08 +#define CPDMA_RXIDVER 0x10 +#define CPDMA_RXCONTROL 0x14 +#define CPDMA_SOFTRESET 0x1c +#define CPDMA_RXTEARDOWN 0x18 +#define CPDMA_TXINTSTATRAW 0x80 +#define CPDMA_TXINTSTATMASKED 0x84 +#define CPDMA_TXINTMASKSET 0x88 +#define CPDMA_TXINTMASKCLEAR 0x8c +#define CPDMA_MACINVECTOR 0x90 +#define CPDMA_MACEOIVECTOR 0x94 +#define CPDMA_RXINTSTATRAW 0xa0 +#define CPDMA_RXINTSTATMASKED 0xa4 +#define CPDMA_RXINTMASKSET 0xa8 +#define CPDMA_RXINTMASKCLEAR 0xac +#define CPDMA_DMAINTSTATRAW 0xb0 +#define CPDMA_DMAINTSTATMASKED 0xb4 +#define CPDMA_DMAINTMASKSET 0xb8 +#define CPDMA_DMAINTMASKCLEAR 0xbc +#define CPDMA_DMAINT_HOSTERR BIT(1) + +/* the following exist only if has_ext_regs is set */ +#define CPDMA_DMACONTROL 0x20 +#define CPDMA_DMASTATUS 0x24 +#define CPDMA_RXBUFFOFS 0x28 +#define CPDMA_EM_CONTROL 0x2c + +/* Descriptor mode bits */ +#define CPDMA_DESC_SOP BIT(31) +#define CPDMA_DESC_EOP BIT(30) +#define CPDMA_DESC_OWNER BIT(29) +#define CPDMA_DESC_EOQ BIT(28) +#define CPDMA_DESC_TD_COMPLETE BIT(27) +#define CPDMA_DESC_PASS_CRC BIT(26) + +#define CPDMA_TEARDOWN_VALUE 0xfffffffc + +struct cpdma_desc { + /* hardware fields */ + u32 hw_next; + u32 hw_buffer; + u32 hw_len; + u32 hw_mode; + /* software fields */ + void *sw_token; + u32 sw_buffer; + u32 sw_len; +}; + +struct cpdma_desc_pool { + u32 phys; + void __iomem *iomap; /* ioremap map */ + void *cpumap; /* dma_alloc map */ + int desc_size, mem_size; + int num_desc, used_desc; + unsigned long *bitmap; + struct device *dev; + spinlock_t lock; +}; + +enum cpdma_state { + CPDMA_STATE_IDLE, + CPDMA_STATE_ACTIVE, + CPDMA_STATE_TEARDOWN, +}; + +const char *cpdma_state_str[] = { "idle", "active", "teardown" }; + +struct cpdma_ctlr { + enum cpdma_state state; + struct cpdma_params params; + struct device *dev; + struct cpdma_desc_pool *pool; + spinlock_t lock; + struct cpdma_chan *channels[2 * CPDMA_MAX_CHANNELS]; +}; + +struct cpdma_chan { + enum cpdma_state state; + struct cpdma_ctlr *ctlr; + int chan_num; + spinlock_t lock; + struct cpdma_desc __iomem *head, *tail; + int count; + void __iomem *hdp, *cp, *rxfree; + u32 mask; + cpdma_handler_fn handler; + enum dma_data_direction dir; + struct cpdma_chan_stats stats; + /* offsets into dmaregs */ + int int_set, int_clear, td; +}; + +/* The following make access to common cpdma_ctlr params more readable */ +#define dmaregs params.dmaregs +#define num_chan params.num_chan + +/* various accessors */ +#define dma_reg_read(ctlr, ofs) __raw_readl((ctlr)->dmaregs + (ofs)) +#define chan_read(chan, fld) __raw_readl((chan)->fld) +#define desc_read(desc, fld) __raw_readl(&(desc)->fld) +#define dma_reg_write(ctlr, ofs, v) __raw_writel(v, (ctlr)->dmaregs + (ofs)) +#define chan_write(chan, fld, v) __raw_writel(v, (chan)->fld) +#define desc_write(desc, fld, v) __raw_writel((u32)(v), &(desc)->fld) + +/* + * Utility constructs for a cpdma descriptor pool. Some devices (e.g. davinci + * emac) have dedicated on-chip memory for these descriptors. Some other + * devices (e.g. cpsw switches) use plain old memory. Descriptor pools + * abstract out these details + */ +static struct cpdma_desc_pool * +cpdma_desc_pool_create(struct device *dev, u32 phys, int size, int align) +{ + int bitmap_size; + struct cpdma_desc_pool *pool; + + pool = kzalloc(sizeof(*pool), GFP_KERNEL); + if (!pool) + return NULL; + + spin_lock_init(&pool->lock); + + pool->dev = dev; + pool->mem_size = size; + pool->desc_size = ALIGN(sizeof(struct cpdma_desc), align); + pool->num_desc = size / pool->desc_size; + + bitmap_size = (pool->num_desc / BITS_PER_LONG) * sizeof(long); + pool->bitmap = kzalloc(bitmap_size, GFP_KERNEL); + if (!pool->bitmap) + goto fail; + + if (phys) { + pool->phys = phys; + pool->iomap = ioremap(phys, size); + } else { + pool->cpumap = dma_alloc_coherent(dev, size, &pool->phys, + GFP_KERNEL); + pool->iomap = (void __force __iomem *)pool->cpumap; + } + + if (pool->iomap) + return pool; + +fail: + kfree(pool->bitmap); + kfree(pool); + return NULL; +} + +static void cpdma_desc_pool_destroy(struct cpdma_desc_pool *pool) +{ + unsigned long flags; + + if (!pool) + return; + + spin_lock_irqsave(&pool->lock, flags); + WARN_ON(pool->used_desc); + kfree(pool->bitmap); + if (pool->cpumap) { + dma_free_coherent(pool->dev, pool->mem_size, pool->cpumap, + pool->phys); + } else { + iounmap(pool->iomap); + } + spin_unlock_irqrestore(&pool->lock, flags); + kfree(pool); +} + +static inline dma_addr_t desc_phys(struct cpdma_desc_pool *pool, + struct cpdma_desc __iomem *desc) +{ + if (!desc) + return 0; + return pool->phys + (__force dma_addr_t)desc - + (__force dma_addr_t)pool->iomap; +} + +static inline struct cpdma_desc __iomem * +desc_from_phys(struct cpdma_desc_pool *pool, dma_addr_t dma) +{ + return dma ? pool->iomap + dma - pool->phys : NULL; +} + +static struct cpdma_desc __iomem * +cpdma_desc_alloc(struct cpdma_desc_pool *pool, int num_desc) +{ + unsigned long flags; + int index; + struct cpdma_desc __iomem *desc = NULL; + + spin_lock_irqsave(&pool->lock, flags); + + index = bitmap_find_next_zero_area(pool->bitmap, pool->num_desc, 0, + num_desc, 0); + if (index < pool->num_desc) { + bitmap_set(pool->bitmap, index, num_desc); + desc = pool->iomap + pool->desc_size * index; + pool->used_desc++; + } + + spin_unlock_irqrestore(&pool->lock, flags); + return desc; +} + +static void cpdma_desc_free(struct cpdma_desc_pool *pool, + struct cpdma_desc __iomem *desc, int num_desc) +{ + unsigned long flags, index; + + index = ((unsigned long)desc - (unsigned long)pool->iomap) / + pool->desc_size; + spin_lock_irqsave(&pool->lock, flags); + bitmap_clear(pool->bitmap, index, num_desc); + pool->used_desc--; + spin_unlock_irqrestore(&pool->lock, flags); +} + +struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params) +{ + struct cpdma_ctlr *ctlr; + + ctlr = kzalloc(sizeof(*ctlr), GFP_KERNEL); + if (!ctlr) + return NULL; + + ctlr->state = CPDMA_STATE_IDLE; + ctlr->params = *params; + ctlr->dev = params->dev; + spin_lock_init(&ctlr->lock); + + ctlr->pool = cpdma_desc_pool_create(ctlr->dev, + ctlr->params.desc_mem_phys, + ctlr->params.desc_mem_size, + ctlr->params.desc_align); + if (!ctlr->pool) { + kfree(ctlr); + return NULL; + } + + if (WARN_ON(ctlr->num_chan > CPDMA_MAX_CHANNELS)) + ctlr->num_chan = CPDMA_MAX_CHANNELS; + return ctlr; +} + +int cpdma_ctlr_start(struct cpdma_ctlr *ctlr) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&ctlr->lock, flags); + if (ctlr->state != CPDMA_STATE_IDLE) { + spin_unlock_irqrestore(&ctlr->lock, flags); + return -EBUSY; + } + + if (ctlr->params.has_soft_reset) { + unsigned long timeout = jiffies + HZ/10; + + dma_reg_write(ctlr, CPDMA_SOFTRESET, 1); + while (time_before(jiffies, timeout)) { + if (dma_reg_read(ctlr, CPDMA_SOFTRESET) == 0) + break; + } + WARN_ON(!time_before(jiffies, timeout)); + } + + for (i = 0; i < ctlr->num_chan; i++) { + __raw_writel(0, ctlr->params.txhdp + 4 * i); + __raw_writel(0, ctlr->params.rxhdp + 4 * i); + __raw_writel(0, ctlr->params.txcp + 4 * i); + __raw_writel(0, ctlr->params.rxcp + 4 * i); + } + + dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff); + dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff); + + dma_reg_write(ctlr, CPDMA_TXCONTROL, 1); + dma_reg_write(ctlr, CPDMA_RXCONTROL, 1); + + ctlr->state = CPDMA_STATE_ACTIVE; + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { + if (ctlr->channels[i]) + cpdma_chan_start(ctlr->channels[i]); + } + spin_unlock_irqrestore(&ctlr->lock, flags); + return 0; +} + +int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr) +{ + unsigned long flags; + int i; + + spin_lock_irqsave(&ctlr->lock, flags); + if (ctlr->state != CPDMA_STATE_ACTIVE) { + spin_unlock_irqrestore(&ctlr->lock, flags); + return -EINVAL; + } + + ctlr->state = CPDMA_STATE_TEARDOWN; + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { + if (ctlr->channels[i]) + cpdma_chan_stop(ctlr->channels[i]); + } + + dma_reg_write(ctlr, CPDMA_RXINTMASKCLEAR, 0xffffffff); + dma_reg_write(ctlr, CPDMA_TXINTMASKCLEAR, 0xffffffff); + + dma_reg_write(ctlr, CPDMA_TXCONTROL, 0); + dma_reg_write(ctlr, CPDMA_RXCONTROL, 0); + + ctlr->state = CPDMA_STATE_IDLE; + + spin_unlock_irqrestore(&ctlr->lock, flags); + return 0; +} + +int cpdma_ctlr_dump(struct cpdma_ctlr *ctlr) +{ + struct device *dev = ctlr->dev; + unsigned long flags; + int i; + + spin_lock_irqsave(&ctlr->lock, flags); + + dev_info(dev, "CPDMA: state: %s", cpdma_state_str[ctlr->state]); + + dev_info(dev, "CPDMA: txidver: %x", + dma_reg_read(ctlr, CPDMA_TXIDVER)); + dev_info(dev, "CPDMA: txcontrol: %x", + dma_reg_read(ctlr, CPDMA_TXCONTROL)); + dev_info(dev, "CPDMA: txteardown: %x", + dma_reg_read(ctlr, CPDMA_TXTEARDOWN)); + dev_info(dev, "CPDMA: rxidver: %x", + dma_reg_read(ctlr, CPDMA_RXIDVER)); + dev_info(dev, "CPDMA: rxcontrol: %x", + dma_reg_read(ctlr, CPDMA_RXCONTROL)); + dev_info(dev, "CPDMA: softreset: %x", + dma_reg_read(ctlr, CPDMA_SOFTRESET)); + dev_info(dev, "CPDMA: rxteardown: %x", + dma_reg_read(ctlr, CPDMA_RXTEARDOWN)); + dev_info(dev, "CPDMA: txintstatraw: %x", + dma_reg_read(ctlr, CPDMA_TXINTSTATRAW)); + dev_info(dev, "CPDMA: txintstatmasked: %x", + dma_reg_read(ctlr, CPDMA_TXINTSTATMASKED)); + dev_info(dev, "CPDMA: txintmaskset: %x", + dma_reg_read(ctlr, CPDMA_TXINTMASKSET)); + dev_info(dev, "CPDMA: txintmaskclear: %x", + dma_reg_read(ctlr, CPDMA_TXINTMASKCLEAR)); + dev_info(dev, "CPDMA: macinvector: %x", + dma_reg_read(ctlr, CPDMA_MACINVECTOR)); + dev_info(dev, "CPDMA: maceoivector: %x", + dma_reg_read(ctlr, CPDMA_MACEOIVECTOR)); + dev_info(dev, "CPDMA: rxintstatraw: %x", + dma_reg_read(ctlr, CPDMA_RXINTSTATRAW)); + dev_info(dev, "CPDMA: rxintstatmasked: %x", + dma_reg_read(ctlr, CPDMA_RXINTSTATMASKED)); + dev_info(dev, "CPDMA: rxintmaskset: %x", + dma_reg_read(ctlr, CPDMA_RXINTMASKSET)); + dev_info(dev, "CPDMA: rxintmaskclear: %x", + dma_reg_read(ctlr, CPDMA_RXINTMASKCLEAR)); + dev_info(dev, "CPDMA: dmaintstatraw: %x", + dma_reg_read(ctlr, CPDMA_DMAINTSTATRAW)); + dev_info(dev, "CPDMA: dmaintstatmasked: %x", + dma_reg_read(ctlr, CPDMA_DMAINTSTATMASKED)); + dev_info(dev, "CPDMA: dmaintmaskset: %x", + dma_reg_read(ctlr, CPDMA_DMAINTMASKSET)); + dev_info(dev, "CPDMA: dmaintmaskclear: %x", + dma_reg_read(ctlr, CPDMA_DMAINTMASKCLEAR)); + + if (!ctlr->params.has_ext_regs) { + dev_info(dev, "CPDMA: dmacontrol: %x", + dma_reg_read(ctlr, CPDMA_DMACONTROL)); + dev_info(dev, "CPDMA: dmastatus: %x", + dma_reg_read(ctlr, CPDMA_DMASTATUS)); + dev_info(dev, "CPDMA: rxbuffofs: %x", + dma_reg_read(ctlr, CPDMA_RXBUFFOFS)); + } + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) + if (ctlr->channels[i]) + cpdma_chan_dump(ctlr->channels[i]); + + spin_unlock_irqrestore(&ctlr->lock, flags); + return 0; +} + +int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr) +{ + unsigned long flags; + int ret = 0, i; + + if (!ctlr) + return -EINVAL; + + spin_lock_irqsave(&ctlr->lock, flags); + if (ctlr->state != CPDMA_STATE_IDLE) + cpdma_ctlr_stop(ctlr); + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { + if (ctlr->channels[i]) + cpdma_chan_destroy(ctlr->channels[i]); + } + + cpdma_desc_pool_destroy(ctlr->pool); + spin_unlock_irqrestore(&ctlr->lock, flags); + kfree(ctlr); + return ret; +} + +int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable) +{ + unsigned long flags; + int i, reg; + + spin_lock_irqsave(&ctlr->lock, flags); + if (ctlr->state != CPDMA_STATE_ACTIVE) { + spin_unlock_irqrestore(&ctlr->lock, flags); + return -EINVAL; + } + + reg = enable ? CPDMA_DMAINTMASKSET : CPDMA_DMAINTMASKCLEAR; + dma_reg_write(ctlr, reg, CPDMA_DMAINT_HOSTERR); + + for (i = 0; i < ARRAY_SIZE(ctlr->channels); i++) { + if (ctlr->channels[i]) + cpdma_chan_int_ctrl(ctlr->channels[i], enable); + } + + spin_unlock_irqrestore(&ctlr->lock, flags); + return 0; +} + +void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr) +{ + dma_reg_write(ctlr, CPDMA_MACEOIVECTOR, 0); +} + +struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num, + cpdma_handler_fn handler) +{ + struct cpdma_chan *chan; + int ret, offset = (chan_num % CPDMA_MAX_CHANNELS) * 4; + unsigned long flags; + + if (__chan_linear(chan_num) >= ctlr->num_chan) + return NULL; + + ret = -ENOMEM; + chan = kzalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) + goto err_chan_alloc; + + spin_lock_irqsave(&ctlr->lock, flags); + ret = -EBUSY; + if (ctlr->channels[chan_num]) + goto err_chan_busy; + + chan->ctlr = ctlr; + chan->state = CPDMA_STATE_IDLE; + chan->chan_num = chan_num; + chan->handler = handler; + + if (is_rx_chan(chan)) { + chan->hdp = ctlr->params.rxhdp + offset; + chan->cp = ctlr->params.rxcp + offset; + chan->rxfree = ctlr->params.rxfree + offset; + chan->int_set = CPDMA_RXINTMASKSET; + chan->int_clear = CPDMA_RXINTMASKCLEAR; + chan->td = CPDMA_RXTEARDOWN; + chan->dir = DMA_FROM_DEVICE; + } else { + chan->hdp = ctlr->params.txhdp + offset; + chan->cp = ctlr->params.txcp + offset; + chan->int_set = CPDMA_TXINTMASKSET; + chan->int_clear = CPDMA_TXINTMASKCLEAR; + chan->td = CPDMA_TXTEARDOWN; + chan->dir = DMA_TO_DEVICE; + } + chan->mask = BIT(chan_linear(chan)); + + spin_lock_init(&chan->lock); + + ctlr->channels[chan_num] = chan; + spin_unlock_irqrestore(&ctlr->lock, flags); + return chan; + +err_chan_busy: + spin_unlock_irqrestore(&ctlr->lock, flags); + kfree(chan); +err_chan_alloc: + return ERR_PTR(ret); +} + +int cpdma_chan_destroy(struct cpdma_chan *chan) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + unsigned long flags; + + if (!chan) + return -EINVAL; + + spin_lock_irqsave(&ctlr->lock, flags); + if (chan->state != CPDMA_STATE_IDLE) + cpdma_chan_stop(chan); + ctlr->channels[chan->chan_num] = NULL; + spin_unlock_irqrestore(&ctlr->lock, flags); + kfree(chan); + return 0; +} + +int cpdma_chan_get_stats(struct cpdma_chan *chan, + struct cpdma_chan_stats *stats) +{ + unsigned long flags; + if (!chan) + return -EINVAL; + spin_lock_irqsave(&chan->lock, flags); + memcpy(stats, &chan->stats, sizeof(*stats)); + spin_unlock_irqrestore(&chan->lock, flags); + return 0; +} + +int cpdma_chan_dump(struct cpdma_chan *chan) +{ + unsigned long flags; + struct device *dev = chan->ctlr->dev; + + spin_lock_irqsave(&chan->lock, flags); + + dev_info(dev, "channel %d (%s %d) state %s", + chan->chan_num, is_rx_chan(chan) ? "rx" : "tx", + chan_linear(chan), cpdma_state_str[chan->state]); + dev_info(dev, "\thdp: %x\n", chan_read(chan, hdp)); + dev_info(dev, "\tcp: %x\n", chan_read(chan, cp)); + if (chan->rxfree) { + dev_info(dev, "\trxfree: %x\n", + chan_read(chan, rxfree)); + } + + dev_info(dev, "\tstats head_enqueue: %d\n", + chan->stats.head_enqueue); + dev_info(dev, "\tstats tail_enqueue: %d\n", + chan->stats.tail_enqueue); + dev_info(dev, "\tstats pad_enqueue: %d\n", + chan->stats.pad_enqueue); + dev_info(dev, "\tstats misqueued: %d\n", + chan->stats.misqueued); + dev_info(dev, "\tstats desc_alloc_fail: %d\n", + chan->stats.desc_alloc_fail); + dev_info(dev, "\tstats pad_alloc_fail: %d\n", + chan->stats.pad_alloc_fail); + dev_info(dev, "\tstats runt_receive_buff: %d\n", + chan->stats.runt_receive_buff); + dev_info(dev, "\tstats runt_transmit_buff: %d\n", + chan->stats.runt_transmit_buff); + dev_info(dev, "\tstats empty_dequeue: %d\n", + chan->stats.empty_dequeue); + dev_info(dev, "\tstats busy_dequeue: %d\n", + chan->stats.busy_dequeue); + dev_info(dev, "\tstats good_dequeue: %d\n", + chan->stats.good_dequeue); + dev_info(dev, "\tstats requeue: %d\n", + chan->stats.requeue); + dev_info(dev, "\tstats teardown_dequeue: %d\n", + chan->stats.teardown_dequeue); + + spin_unlock_irqrestore(&chan->lock, flags); + return 0; +} + +static void __cpdma_chan_submit(struct cpdma_chan *chan, + struct cpdma_desc __iomem *desc) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc __iomem *prev = chan->tail; + struct cpdma_desc_pool *pool = ctlr->pool; + dma_addr_t desc_dma; + u32 mode; + + desc_dma = desc_phys(pool, desc); + + /* simple case - idle channel */ + if (!chan->head) { + chan->stats.head_enqueue++; + chan->head = desc; + chan->tail = desc; + if (chan->state == CPDMA_STATE_ACTIVE) + chan_write(chan, hdp, desc_dma); + return; + } + + /* first chain the descriptor at the tail of the list */ + desc_write(prev, hw_next, desc_dma); + chan->tail = desc; + chan->stats.tail_enqueue++; + + /* next check if EOQ has been triggered already */ + mode = desc_read(prev, hw_mode); + if (((mode & (CPDMA_DESC_EOQ | CPDMA_DESC_OWNER)) == CPDMA_DESC_EOQ) && + (chan->state == CPDMA_STATE_ACTIVE)) { + desc_write(prev, hw_mode, mode & ~CPDMA_DESC_EOQ); + chan_write(chan, hdp, desc_dma); + chan->stats.misqueued++; + } +} + +int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data, + int len, gfp_t gfp_mask) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc __iomem *desc; + dma_addr_t buffer; + unsigned long flags; + u32 mode; + int ret = 0; + + spin_lock_irqsave(&chan->lock, flags); + + if (chan->state == CPDMA_STATE_TEARDOWN) { + ret = -EINVAL; + goto unlock_ret; + } + + desc = cpdma_desc_alloc(ctlr->pool, 1); + if (!desc) { + chan->stats.desc_alloc_fail++; + ret = -ENOMEM; + goto unlock_ret; + } + + if (len < ctlr->params.min_packet_size) { + len = ctlr->params.min_packet_size; + chan->stats.runt_transmit_buff++; + } + + buffer = dma_map_single(ctlr->dev, data, len, chan->dir); + mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP; + + desc_write(desc, hw_next, 0); + desc_write(desc, hw_buffer, buffer); + desc_write(desc, hw_len, len); + desc_write(desc, hw_mode, mode | len); + desc_write(desc, sw_token, token); + desc_write(desc, sw_buffer, buffer); + desc_write(desc, sw_len, len); + + __cpdma_chan_submit(chan, desc); + + if (chan->state == CPDMA_STATE_ACTIVE && chan->rxfree) + chan_write(chan, rxfree, 1); + + chan->count++; + +unlock_ret: + spin_unlock_irqrestore(&chan->lock, flags); + return ret; +} + +static void __cpdma_chan_free(struct cpdma_chan *chan, + struct cpdma_desc __iomem *desc, + int outlen, int status) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc_pool *pool = ctlr->pool; + dma_addr_t buff_dma; + int origlen; + void *token; + + token = (void *)desc_read(desc, sw_token); + buff_dma = desc_read(desc, sw_buffer); + origlen = desc_read(desc, sw_len); + + dma_unmap_single(ctlr->dev, buff_dma, origlen, chan->dir); + cpdma_desc_free(pool, desc, 1); + (*chan->handler)(token, outlen, status); +} + +static int __cpdma_chan_process(struct cpdma_chan *chan) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc __iomem *desc; + int status, outlen; + struct cpdma_desc_pool *pool = ctlr->pool; + dma_addr_t desc_dma; + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + + desc = chan->head; + if (!desc) { + chan->stats.empty_dequeue++; + status = -ENOENT; + goto unlock_ret; + } + desc_dma = desc_phys(pool, desc); + + status = __raw_readl(&desc->hw_mode); + outlen = status & 0x7ff; + if (status & CPDMA_DESC_OWNER) { + chan->stats.busy_dequeue++; + status = -EBUSY; + goto unlock_ret; + } + status = status & (CPDMA_DESC_EOQ | CPDMA_DESC_TD_COMPLETE); + + chan->head = desc_from_phys(pool, desc_read(desc, hw_next)); + chan_write(chan, cp, desc_dma); + chan->count--; + chan->stats.good_dequeue++; + + if (status & CPDMA_DESC_EOQ) { + chan->stats.requeue++; + chan_write(chan, hdp, desc_phys(pool, chan->head)); + } + + spin_unlock_irqrestore(&chan->lock, flags); + + __cpdma_chan_free(chan, desc, outlen, status); + return status; + +unlock_ret: + spin_unlock_irqrestore(&chan->lock, flags); + return status; +} + +int cpdma_chan_process(struct cpdma_chan *chan, int quota) +{ + int used = 0, ret = 0; + + if (chan->state != CPDMA_STATE_ACTIVE) + return -EINVAL; + + while (used < quota) { + ret = __cpdma_chan_process(chan); + if (ret < 0) + break; + used++; + } + return used; +} + +int cpdma_chan_start(struct cpdma_chan *chan) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc_pool *pool = ctlr->pool; + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + if (chan->state != CPDMA_STATE_IDLE) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EBUSY; + } + if (ctlr->state != CPDMA_STATE_ACTIVE) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EINVAL; + } + dma_reg_write(ctlr, chan->int_set, chan->mask); + chan->state = CPDMA_STATE_ACTIVE; + if (chan->head) { + chan_write(chan, hdp, desc_phys(pool, chan->head)); + if (chan->rxfree) + chan_write(chan, rxfree, chan->count); + } + + spin_unlock_irqrestore(&chan->lock, flags); + return 0; +} + +int cpdma_chan_stop(struct cpdma_chan *chan) +{ + struct cpdma_ctlr *ctlr = chan->ctlr; + struct cpdma_desc_pool *pool = ctlr->pool; + unsigned long flags; + int ret; + unsigned long timeout; + + spin_lock_irqsave(&chan->lock, flags); + if (chan->state != CPDMA_STATE_ACTIVE) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EINVAL; + } + + chan->state = CPDMA_STATE_TEARDOWN; + dma_reg_write(ctlr, chan->int_clear, chan->mask); + + /* trigger teardown */ + dma_reg_write(ctlr, chan->td, chan->chan_num); + + /* wait for teardown complete */ + timeout = jiffies + HZ/10; /* 100 msec */ + while (time_before(jiffies, timeout)) { + u32 cp = chan_read(chan, cp); + if ((cp & CPDMA_TEARDOWN_VALUE) == CPDMA_TEARDOWN_VALUE) + break; + cpu_relax(); + } + WARN_ON(!time_before(jiffies, timeout)); + chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); + + /* handle completed packets */ + do { + ret = __cpdma_chan_process(chan); + if (ret < 0) + break; + } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0); + + /* remaining packets haven't been tx/rx'ed, clean them up */ + while (chan->head) { + struct cpdma_desc __iomem *desc = chan->head; + dma_addr_t next_dma; + + next_dma = desc_read(desc, hw_next); + chan->head = desc_from_phys(pool, next_dma); + chan->stats.teardown_dequeue++; + + /* issue callback without locks held */ + spin_unlock_irqrestore(&chan->lock, flags); + __cpdma_chan_free(chan, desc, 0, -ENOSYS); + spin_lock_irqsave(&chan->lock, flags); + } + + chan->state = CPDMA_STATE_IDLE; + spin_unlock_irqrestore(&chan->lock, flags); + return 0; +} + +int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable) +{ + unsigned long flags; + + spin_lock_irqsave(&chan->lock, flags); + if (chan->state != CPDMA_STATE_ACTIVE) { + spin_unlock_irqrestore(&chan->lock, flags); + return -EINVAL; + } + + dma_reg_write(chan->ctlr, enable ? chan->int_set : chan->int_clear, + chan->mask); + spin_unlock_irqrestore(&chan->lock, flags); + + return 0; +} + +struct cpdma_control_info { + u32 reg; + u32 shift, mask; + int access; +#define ACCESS_RO BIT(0) +#define ACCESS_WO BIT(1) +#define ACCESS_RW (ACCESS_RO | ACCESS_WO) +}; + +struct cpdma_control_info controls[] = { + [CPDMA_CMD_IDLE] = {CPDMA_DMACONTROL, 3, 1, ACCESS_WO}, + [CPDMA_COPY_ERROR_FRAMES] = {CPDMA_DMACONTROL, 4, 1, ACCESS_RW}, + [CPDMA_RX_OFF_LEN_UPDATE] = {CPDMA_DMACONTROL, 2, 1, ACCESS_RW}, + [CPDMA_RX_OWNERSHIP_FLIP] = {CPDMA_DMACONTROL, 1, 1, ACCESS_RW}, + [CPDMA_TX_PRIO_FIXED] = {CPDMA_DMACONTROL, 0, 1, ACCESS_RW}, + [CPDMA_STAT_IDLE] = {CPDMA_DMASTATUS, 31, 1, ACCESS_RO}, + [CPDMA_STAT_TX_ERR_CODE] = {CPDMA_DMASTATUS, 20, 0xf, ACCESS_RW}, + [CPDMA_STAT_TX_ERR_CHAN] = {CPDMA_DMASTATUS, 16, 0x7, ACCESS_RW}, + [CPDMA_STAT_RX_ERR_CODE] = {CPDMA_DMASTATUS, 12, 0xf, ACCESS_RW}, + [CPDMA_STAT_RX_ERR_CHAN] = {CPDMA_DMASTATUS, 8, 0x7, ACCESS_RW}, + [CPDMA_RX_BUFFER_OFFSET] = {CPDMA_RXBUFFOFS, 0, 0xffff, ACCESS_RW}, +}; + +int cpdma_control_get(struct cpdma_ctlr *ctlr, int control) +{ + unsigned long flags; + struct cpdma_control_info *info = &controls[control]; + int ret; + + spin_lock_irqsave(&ctlr->lock, flags); + + ret = -ENOTSUPP; + if (!ctlr->params.has_ext_regs) + goto unlock_ret; + + ret = -EINVAL; + if (ctlr->state != CPDMA_STATE_ACTIVE) + goto unlock_ret; + + ret = -ENOENT; + if (control < 0 || control >= ARRAY_SIZE(controls)) + goto unlock_ret; + + ret = -EPERM; + if ((info->access & ACCESS_RO) != ACCESS_RO) + goto unlock_ret; + + ret = (dma_reg_read(ctlr, info->reg) >> info->shift) & info->mask; + +unlock_ret: + spin_unlock_irqrestore(&ctlr->lock, flags); + return ret; +} + +int cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value) +{ + unsigned long flags; + struct cpdma_control_info *info = &controls[control]; + int ret; + u32 val; + + spin_lock_irqsave(&ctlr->lock, flags); + + ret = -ENOTSUPP; + if (!ctlr->params.has_ext_regs) + goto unlock_ret; + + ret = -EINVAL; + if (ctlr->state != CPDMA_STATE_ACTIVE) + goto unlock_ret; + + ret = -ENOENT; + if (control < 0 || control >= ARRAY_SIZE(controls)) + goto unlock_ret; + + ret = -EPERM; + if ((info->access & ACCESS_WO) != ACCESS_WO) + goto unlock_ret; + + val = dma_reg_read(ctlr, info->reg); + val &= ~(info->mask << info->shift); + val |= (value & info->mask) << info->shift; + dma_reg_write(ctlr, info->reg, val); + ret = 0; + +unlock_ret: + spin_unlock_irqrestore(&ctlr->lock, flags); + return ret; +} diff --git a/drivers/net/davinci_cpdma.h b/drivers/net/davinci_cpdma.h new file mode 100644 index 0000000..868e50e --- /dev/null +++ b/drivers/net/davinci_cpdma.h @@ -0,0 +1,108 @@ +/* + * Texas Instruments CPDMA Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#ifndef __DAVINCI_CPDMA_H__ +#define __DAVINCI_CPDMA_H__ + +#define CPDMA_MAX_CHANNELS BITS_PER_LONG + +#define tx_chan_num(chan) (chan) +#define rx_chan_num(chan) ((chan) + CPDMA_MAX_CHANNELS) +#define is_rx_chan(chan) ((chan)->chan_num >= CPDMA_MAX_CHANNELS) +#define is_tx_chan(chan) (!is_rx_chan(chan)) +#define __chan_linear(chan_num) ((chan_num) & (CPDMA_MAX_CHANNELS - 1)) +#define chan_linear(chan) __chan_linear((chan)->chan_num) + +struct cpdma_params { + struct device *dev; + void __iomem *dmaregs; + void __iomem *txhdp, *rxhdp, *txcp, *rxcp; + void __iomem *rxthresh, *rxfree; + int num_chan; + bool has_soft_reset; + int min_packet_size; + u32 desc_mem_phys; + int desc_mem_size; + int desc_align; + + /* + * Some instances of embedded cpdma controllers have extra control and + * status registers. The following flag enables access to these + * "extended" registers. + */ + bool has_ext_regs; +}; + +struct cpdma_chan_stats { + u32 head_enqueue; + u32 tail_enqueue; + u32 pad_enqueue; + u32 misqueued; + u32 desc_alloc_fail; + u32 pad_alloc_fail; + u32 runt_receive_buff; + u32 runt_transmit_buff; + u32 empty_dequeue; + u32 busy_dequeue; + u32 good_dequeue; + u32 requeue; + u32 teardown_dequeue; +}; + +struct cpdma_ctlr; +struct cpdma_chan; + +typedef void (*cpdma_handler_fn)(void *token, int len, int status); + +struct cpdma_ctlr *cpdma_ctlr_create(struct cpdma_params *params); +int cpdma_ctlr_destroy(struct cpdma_ctlr *ctlr); +int cpdma_ctlr_start(struct cpdma_ctlr *ctlr); +int cpdma_ctlr_stop(struct cpdma_ctlr *ctlr); +int cpdma_ctlr_dump(struct cpdma_ctlr *ctlr); + +struct cpdma_chan *cpdma_chan_create(struct cpdma_ctlr *ctlr, int chan_num, + cpdma_handler_fn handler); +int cpdma_chan_destroy(struct cpdma_chan *chan); +int cpdma_chan_start(struct cpdma_chan *chan); +int cpdma_chan_stop(struct cpdma_chan *chan); +int cpdma_chan_dump(struct cpdma_chan *chan); + +int cpdma_chan_get_stats(struct cpdma_chan *chan, + struct cpdma_chan_stats *stats); +int cpdma_chan_submit(struct cpdma_chan *chan, void *token, void *data, + int len, gfp_t gfp_mask); +int cpdma_chan_process(struct cpdma_chan *chan, int quota); + +int cpdma_ctlr_int_ctrl(struct cpdma_ctlr *ctlr, bool enable); +void cpdma_ctlr_eoi(struct cpdma_ctlr *ctlr); +int cpdma_chan_int_ctrl(struct cpdma_chan *chan, bool enable); + +enum cpdma_control { + CPDMA_CMD_IDLE, /* write-only */ + CPDMA_COPY_ERROR_FRAMES, /* read-write */ + CPDMA_RX_OFF_LEN_UPDATE, /* read-write */ + CPDMA_RX_OWNERSHIP_FLIP, /* read-write */ + CPDMA_TX_PRIO_FIXED, /* read-write */ + CPDMA_STAT_IDLE, /* read-only */ + CPDMA_STAT_TX_ERR_CHAN, /* read-only */ + CPDMA_STAT_TX_ERR_CODE, /* read-only */ + CPDMA_STAT_RX_ERR_CHAN, /* read-only */ + CPDMA_STAT_RX_ERR_CODE, /* read-only */ + CPDMA_RX_BUFFER_OFFSET, /* read-write */ +}; + +int cpdma_control_get(struct cpdma_ctlr *ctlr, int control); +int cpdma_control_set(struct cpdma_ctlr *ctlr, int control, int value); + +#endif -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:03 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:03 -0700 Subject: [PATCH 39/47] net: davinci_emac: switch to new cpdma layer In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-40-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch hooks up the emac driver with the newly separated cpdma driver. Key differences introduced here: - The old buffer list scheme is no longer required - The original code maintained mac address per rx channel, even if only one rx channel was being used. With this change, mac address is maintained device wide. If support for multiple rx channels is added in future, this will need to be reworked a bit. - The new CPDMA code handles short packets better than before. The earlier code was adjusting the length up, without ensuring that the tail end of the padding was cleared - a possible security issue. This has been fixed to use skb_padto(). Signed-off-by: Cyril Chemparathy Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/davinci_emac.c | 249 +++++++++++++++++++++++++++++--------------- 1 files changed, 164 insertions(+), 85 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index d4298cb..67dbcfb 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -63,6 +63,8 @@ #include #include +#include "davinci_cpdma.h" + static int debug_level; module_param(debug_level, int, 0); MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)"); @@ -113,6 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DEF_MAX_FRAME_SIZE (1500 + 14 + 4 + 4) #define EMAC_DEF_TX_CH (0) /* Default 0th channel */ #define EMAC_DEF_RX_CH (0) /* Default 0th channel */ +#define EMAC_DEF_RX_NUM_DESC (128) #define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */ #define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */ #define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */ @@ -460,6 +463,9 @@ struct emac_priv { u32 hw_ram_addr; struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; + struct cpdma_ctlr *dma; + struct cpdma_chan *txchan; + struct cpdma_chan *rxchan; u32 link; /* 1=link on, 0=link off */ u32 speed; /* 0=Auto Neg, 1=No PHY, 10,100, 1000 - mbps */ u32 duplex; /* Link duplex: 0=Half, 1=Full */ @@ -624,6 +630,8 @@ static void emac_dump_regs(struct emac_priv *priv) emac_read(EMAC_RXMOFOVERRUNS)); dev_info(emac_dev, "EMAC: rx_dma_overruns:%d\n", emac_read(EMAC_RXDMAOVERRUNS)); + + cpdma_ctlr_dump(priv->dma); } /** @@ -1151,6 +1159,70 @@ static irqreturn_t emac_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static struct sk_buff *emac_rx_alloc(struct emac_priv *priv) +{ + struct sk_buff *skb = dev_alloc_skb(priv->rx_buf_size); + if (WARN_ON(!skb)) + return NULL; + skb->dev = priv->ndev; + skb_reserve(skb, NET_IP_ALIGN); + return skb; +} + +static void emac_rx_handler(void *token, int len, int status) +{ + struct sk_buff *skb = token; + struct net_device *ndev = skb->dev; + struct emac_priv *priv = netdev_priv(ndev); + struct device *emac_dev = &ndev->dev; + int ret; + + /* free and bail if we are shutting down */ + if (unlikely(!netif_running(ndev))) { + dev_kfree_skb_any(skb); + return; + } + + /* recycle on recieve error */ + if (status < 0) { + ndev->stats.rx_errors++; + goto recycle; + } + + /* feed received packet up the stack */ + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, ndev); + netif_receive_skb(skb); + ndev->stats.rx_bytes += len; + ndev->stats.rx_packets++; + + /* alloc a new packet for receive */ + skb = emac_rx_alloc(priv); + if (!skb) { + if (netif_msg_rx_err(priv) && net_ratelimit()) + dev_err(emac_dev, "failed rx buffer alloc\n"); + return; + } + +recycle: + ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, + skb_tailroom(skb), GFP_KERNEL); + if (WARN_ON(ret < 0)) + dev_kfree_skb_any(skb); +} + +static void emac_tx_handler(void *token, int len, int status) +{ + struct sk_buff *skb = token; + struct net_device *ndev = skb->dev; + + if (unlikely(netif_queue_stopped(ndev))) + netif_start_queue(ndev); + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += len; + dev_kfree_skb_any(skb); +} + /** EMAC on-chip buffer descriptor memory * * WARNING: Please note that the on chip memory is used for both TX and RX @@ -1532,42 +1604,36 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) { struct device *emac_dev = &ndev->dev; int ret_code; - struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */ - struct emac_netpktobj tx_packet; /* packet object */ struct emac_priv *priv = netdev_priv(ndev); /* If no link, return */ if (unlikely(!priv->link)) { if (netif_msg_tx_err(priv) && net_ratelimit()) dev_err(emac_dev, "DaVinci EMAC: No link to transmit"); - return NETDEV_TX_BUSY; + goto fail_tx; } - /* Build the buffer and packet objects - Since only single fragment is - * supported, need not set length and token in both packet & object. - * Doing so for completeness sake & to show that this needs to be done - * in multifragment case - */ - tx_packet.buf_list = &tx_buf; - tx_packet.num_bufs = 1; /* only single fragment supported */ - tx_packet.pkt_length = skb->len; - tx_packet.pkt_token = (void *)skb; - tx_buf.length = skb->len; - tx_buf.buf_token = (void *)skb; - tx_buf.data_ptr = skb->data; - ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH); + ret_code = skb_padto(skb, EMAC_DEF_MIN_ETHPKTSIZE); + if (unlikely(ret_code < 0)) { + if (netif_msg_tx_err(priv) && net_ratelimit()) + dev_err(emac_dev, "DaVinci EMAC: packet pad failed"); + goto fail_tx; + } + + ret_code = cpdma_chan_submit(priv->txchan, skb, skb->data, skb->len, + GFP_KERNEL); if (unlikely(ret_code != 0)) { - if (ret_code == EMAC_ERR_TX_OUT_OF_BD) { - if (netif_msg_tx_err(priv) && net_ratelimit()) - dev_err(emac_dev, "DaVinci EMAC: xmit() fatal"\ - " err. Out of TX BD's"); - netif_stop_queue(priv->ndev); - } - ndev->stats.tx_dropped++; - return NETDEV_TX_BUSY; + if (netif_msg_tx_err(priv) && net_ratelimit()) + dev_err(emac_dev, "DaVinci EMAC: desc submit failed"); + goto fail_tx; } return NETDEV_TX_OK; + +fail_tx: + ndev->stats.tx_dropped++; + netif_stop_queue(ndev); + return NETDEV_TX_BUSY; } /** @@ -1588,13 +1654,12 @@ static void emac_dev_tx_timeout(struct net_device *ndev) if (netif_msg_tx_err(priv)) dev_err(emac_dev, "DaVinci EMAC: xmit timeout, restarting TX"); + emac_dump_regs(priv); + ndev->stats.tx_errors++; emac_int_disable(priv); - emac_stop_txch(priv, EMAC_DEF_TX_CH); - emac_cleanup_txch(priv, EMAC_DEF_TX_CH); - emac_init_txch(priv, EMAC_DEF_TX_CH); - emac_write(EMAC_TXHDP(0), 0); - emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH)); + cpdma_chan_stop(priv->txchan); + cpdma_chan_start(priv->txchan); emac_int_enable(priv); } @@ -1915,7 +1980,6 @@ static void emac_setmac(struct emac_priv *priv, u32 ch, char *mac_addr) static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) { struct emac_priv *priv = netdev_priv(ndev); - struct emac_rxch *rxch = priv->rxch[EMAC_DEF_RX_CH]; struct device *emac_dev = &priv->ndev->dev; struct sockaddr *sa = addr; @@ -1926,11 +1990,10 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len); - /* If the interface is down - rxch is NULL. */ /* MAC address is configured only after the interface is enabled. */ if (netif_running(ndev)) { - memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len); - emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr); + memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len); + emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr); } if (netif_msg_drv(priv)) @@ -2139,7 +2202,7 @@ end_emac_rx_bdproc: */ static int emac_hw_enable(struct emac_priv *priv) { - u32 ch, val, mbp_enable, mac_control; + u32 val, mbp_enable, mac_control; /* Soft reset */ emac_write(EMAC_SOFTRESET, 1); @@ -2182,26 +2245,9 @@ static int emac_hw_enable(struct emac_priv *priv) emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL); priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF; - val = emac_read(EMAC_TXCONTROL); - val |= EMAC_TX_CONTROL_TX_ENABLE_VAL; - emac_write(EMAC_TXCONTROL, val); - val = emac_read(EMAC_RXCONTROL); - val |= EMAC_RX_CONTROL_RX_ENABLE_VAL; - emac_write(EMAC_RXCONTROL, val); emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL); - for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) { - emac_write(EMAC_TXHDP(ch), 0); - emac_write(EMAC_TXINTMASKSET, BIT(ch)); - } - for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) { - struct emac_rxch *rxch = priv->rxch[ch]; - emac_setmac(priv, ch, rxch->mac_addr); - emac_write(EMAC_RXINTMASKSET, BIT(ch)); - rxch->queue_active = 1; - emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head, priv)); - } + emac_setmac(priv, EMAC_DEF_RX_CH, priv->mac_addr); /* Enable MII */ val = emac_read(EMAC_MACCONTROL); @@ -2246,8 +2292,8 @@ static int emac_poll(struct napi_struct *napi, int budget) mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC; if (status & mask) { - num_tx_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH, - EMAC_DEF_TX_MAX_SERVICE); + num_tx_pkts = cpdma_chan_process(priv->txchan, + EMAC_DEF_TX_MAX_SERVICE); } /* TX processing */ mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC; @@ -2256,7 +2302,7 @@ static int emac_poll(struct napi_struct *napi, int budget) mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC; if (status & mask) { - num_rx_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget); + num_rx_pkts = cpdma_chan_process(priv->rxchan, budget); } /* RX processing */ mask = EMAC_DM644X_MAC_IN_VECTOR_HOST_INT; @@ -2397,9 +2443,9 @@ static int match_first_device(struct device *dev, void *data) static int emac_dev_open(struct net_device *ndev) { struct device *emac_dev = &ndev->dev; - u32 rc, cnt, ch; + u32 cnt; struct resource *res; - int q, m; + int q, m, ret; int i = 0; int k = 0; struct emac_priv *priv = netdev_priv(ndev); @@ -2411,29 +2457,21 @@ static int emac_dev_open(struct net_device *ndev) /* Configuration items */ priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN; - /* Clear basic hardware */ - for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) { - emac_write(EMAC_TXHDP(ch), 0); - emac_write(EMAC_RXHDP(ch), 0); - emac_write(EMAC_RXHDP(ch), 0); - emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR); - emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR); - } priv->mac_hash1 = 0; priv->mac_hash2 = 0; emac_write(EMAC_MACHASH1, 0); emac_write(EMAC_MACHASH2, 0); - /* multi ch not supported - open 1 TX, 1RX ch by default */ - rc = emac_init_txch(priv, EMAC_DEF_TX_CH); - if (0 != rc) { - dev_err(emac_dev, "DaVinci EMAC: emac_init_txch() failed"); - return rc; - } - rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr); - if (0 != rc) { - dev_err(emac_dev, "DaVinci EMAC: emac_init_rxch() failed"); - return rc; + for (i = 0; i < EMAC_DEF_RX_NUM_DESC; i++) { + struct sk_buff *skb = emac_rx_alloc(priv); + + if (!skb) + break; + + ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, + skb_tailroom(skb), GFP_KERNEL); + if (WARN_ON(ret < 0)) + break; } /* Request IRQ */ @@ -2458,6 +2496,8 @@ static int emac_dev_open(struct net_device *ndev) emac_set_coalesce(ndev, &coal); } + cpdma_ctlr_start(priv->dma); + priv->phydev = NULL; /* use the first phy on the bus if pdata did not give us a phy id */ if (!priv->phy_id) { @@ -2545,10 +2585,7 @@ static int emac_dev_stop(struct net_device *ndev) netif_carrier_off(ndev); emac_int_disable(priv); - emac_stop_txch(priv, EMAC_DEF_TX_CH); - emac_stop_rxch(priv, EMAC_DEF_RX_CH); - emac_cleanup_txch(priv, EMAC_DEF_TX_CH); - emac_cleanup_rxch(priv, EMAC_DEF_RX_CH); + cpdma_ctlr_stop(priv->dma); emac_write(EMAC_SOFTRESET, 1); if (priv->phydev) @@ -2653,9 +2690,10 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) struct resource *res; struct net_device *ndev; struct emac_priv *priv; - unsigned long size; + unsigned long size, hw_ram_addr; struct emac_platform_data *pdata; struct device *emac_dev; + struct cpdma_params dma_params; /* obtain emac clock from kernel */ emac_clk = clk_get(&pdev->dev, NULL); @@ -2731,11 +2769,40 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->ctrl_ram_size = pdata->ctrl_ram_size; priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; - if (pdata->hw_ram_addr) - priv->hw_ram_addr = pdata->hw_ram_addr; - else - priv->hw_ram_addr = (u32 __force)res->start + - pdata->ctrl_ram_offset; + hw_ram_addr = pdata->hw_ram_addr; + if (!hw_ram_addr) + hw_ram_addr = (u32 __force)res->start + pdata->ctrl_ram_offset; + + memset(&dma_params, 0, sizeof(dma_params)); + dma_params.dev = emac_dev; + dma_params.dmaregs = priv->emac_base; + dma_params.rxthresh = priv->emac_base + 0x120; + dma_params.rxfree = priv->emac_base + 0x140; + dma_params.txhdp = priv->emac_base + 0x600; + dma_params.rxhdp = priv->emac_base + 0x620; + dma_params.txcp = priv->emac_base + 0x640; + dma_params.rxcp = priv->emac_base + 0x660; + dma_params.num_chan = EMAC_MAX_TXRX_CHANNELS; + dma_params.min_packet_size = EMAC_DEF_MIN_ETHPKTSIZE; + dma_params.desc_mem_phys = hw_ram_addr; + dma_params.desc_mem_size = pdata->ctrl_ram_size; + dma_params.desc_align = 16; + + priv->dma = cpdma_ctlr_create(&dma_params); + if (!priv->dma) { + dev_err(emac_dev, "DaVinci EMAC: Error initializing DMA\n"); + rc = -ENOMEM; + goto no_dma; + } + + priv->txchan = cpdma_chan_create(priv->dma, tx_chan_num(EMAC_DEF_TX_CH), + emac_tx_handler); + priv->rxchan = cpdma_chan_create(priv->dma, rx_chan_num(EMAC_DEF_RX_CH), + emac_rx_handler); + if (WARN_ON(!priv->txchan || !priv->rxchan)) { + rc = -ENOMEM; + goto no_irq_res; + } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { @@ -2778,6 +2845,12 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) netdev_reg_err: clk_disable(emac_clk); no_irq_res: + if (priv->txchan) + cpdma_chan_destroy(priv->txchan); + if (priv->rxchan) + cpdma_chan_destroy(priv->rxchan); + cpdma_ctlr_destroy(priv->dma); +no_dma: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start + 1); iounmap(priv->remap_addr); @@ -2806,6 +2879,12 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (priv->txchan) + cpdma_chan_destroy(priv->txchan); + if (priv->rxchan) + cpdma_chan_destroy(priv->rxchan); + cpdma_ctlr_destroy(priv->dma); + release_mem_region(res->start, res->end - res->start + 1); unregister_netdev(ndev); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:04 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:04 -0700 Subject: [PATCH 40/47] net: davinci_emac: cleanup unused cpdma code In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-41-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy Having switched over to the newly introduced cpdma layer, this patch now removes a whole bunch of code that is now unused. This patch has been maintained separate strictly for reasons of readability. Signed-off-by: Cyril Chemparathy Acked-by: David S. Miller Tested-by: Michael Williamson Tested-by: Caglar Akyuz Signed-off-by: Kevin Hilman --- drivers/net/davinci_emac.c | 930 -------------------------------------------- 1 files changed, 0 insertions(+), 930 deletions(-) diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index 67dbcfb..2a628d1 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -127,7 +127,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; /* EMAC register related defines */ #define EMAC_ALL_MULTI_REG_VALUE (0xFFFFFFFF) #define EMAC_NUM_MULTICAST_BITS (64) -#define EMAC_TEARDOWN_VALUE (0xFFFFFFFC) #define EMAC_TX_CONTROL_TX_ENABLE_VAL (0x1) #define EMAC_RX_CONTROL_RX_ENABLE_VAL (0x1) #define EMAC_MAC_HOST_ERR_INTMASK_VAL (0x2) @@ -214,24 +213,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_DEF_MAX_MULTICAST_ADDRESSES (64) /* Max mcast addr's */ /* EMAC Peripheral Device Register Memory Layout structure */ -#define EMAC_TXIDVER 0x0 -#define EMAC_TXCONTROL 0x4 -#define EMAC_TXTEARDOWN 0x8 -#define EMAC_RXIDVER 0x10 -#define EMAC_RXCONTROL 0x14 -#define EMAC_RXTEARDOWN 0x18 -#define EMAC_TXINTSTATRAW 0x80 -#define EMAC_TXINTSTATMASKED 0x84 -#define EMAC_TXINTMASKSET 0x88 -#define EMAC_TXINTMASKCLEAR 0x8C #define EMAC_MACINVECTOR 0x90 #define EMAC_DM646X_MACEOIVECTOR 0x94 -#define EMAC_RXINTSTATRAW 0xA0 -#define EMAC_RXINTSTATMASKED 0xA4 -#define EMAC_RXINTMASKSET 0xA8 -#define EMAC_RXINTMASKCLEAR 0xAC #define EMAC_MACINTSTATRAW 0xB0 #define EMAC_MACINTSTATMASKED 0xB4 #define EMAC_MACINTMASKSET 0xB8 @@ -258,12 +243,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; #define EMAC_MACADDRHI 0x504 #define EMAC_MACINDEX 0x508 -/* EMAC HDP and Completion registors */ -#define EMAC_TXHDP(ch) (0x600 + (ch * 4)) -#define EMAC_RXHDP(ch) (0x620 + (ch * 4)) -#define EMAC_TXCP(ch) (0x640 + (ch * 4)) -#define EMAC_RXCP(ch) (0x660 + (ch * 4)) - /* EMAC statistics registers */ #define EMAC_RXGOODFRAMES 0x200 #define EMAC_RXBCASTFRAMES 0x204 @@ -328,120 +307,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; /* EMAC Stats Clear Mask */ #define EMAC_STATS_CLR_MASK (0xFFFFFFFF) -/** net_buf_obj: EMAC network bufferdata structure - * - * EMAC network buffer data structure - */ -struct emac_netbufobj { - void *buf_token; - char *data_ptr; - int length; -}; - -/** net_pkt_obj: EMAC network packet data structure - * - * EMAC network packet data structure - supports buffer list (for future) - */ -struct emac_netpktobj { - void *pkt_token; /* data token may hold tx/rx chan id */ - struct emac_netbufobj *buf_list; /* array of network buffer objects */ - int num_bufs; - int pkt_length; -}; - -/** emac_tx_bd: EMAC TX Buffer descriptor data structure - * - * EMAC TX Buffer descriptor data structure - */ -struct emac_tx_bd { - int h_next; - int buff_ptr; - int off_b_len; - int mode; /* SOP, EOP, ownership, EOQ, teardown,Qstarv, length */ - struct emac_tx_bd __iomem *next; - void *buf_token; -}; - -/** emac_txch: EMAC TX Channel data structure - * - * EMAC TX Channel data structure - */ -struct emac_txch { - /* Config related */ - u32 num_bd; - u32 service_max; - - /* CPPI specific */ - u32 alloc_size; - void __iomem *bd_mem; - struct emac_tx_bd __iomem *bd_pool_head; - struct emac_tx_bd __iomem *active_queue_head; - struct emac_tx_bd __iomem *active_queue_tail; - struct emac_tx_bd __iomem *last_hw_bdprocessed; - u32 queue_active; - u32 teardown_pending; - u32 *tx_complete; - - /** statistics */ - u32 proc_count; /* TX: # of times emac_tx_bdproc is called */ - u32 mis_queued_packets; - u32 queue_reinit; - u32 end_of_queue_add; - u32 out_of_tx_bd; - u32 no_active_pkts; /* IRQ when there were no packets to process */ - u32 active_queue_count; -}; - -/** emac_rx_bd: EMAC RX Buffer descriptor data structure - * - * EMAC RX Buffer descriptor data structure - */ -struct emac_rx_bd { - int h_next; - int buff_ptr; - int off_b_len; - int mode; - struct emac_rx_bd __iomem *next; - void *data_ptr; - void *buf_token; -}; - -/** emac_rxch: EMAC RX Channel data structure - * - * EMAC RX Channel data structure - */ -struct emac_rxch { - /* configuration info */ - u32 num_bd; - u32 service_max; - u32 buf_size; - char mac_addr[6]; - - /** CPPI specific */ - u32 alloc_size; - void __iomem *bd_mem; - struct emac_rx_bd __iomem *bd_pool_head; - struct emac_rx_bd __iomem *active_queue_head; - struct emac_rx_bd __iomem *active_queue_tail; - u32 queue_active; - u32 teardown_pending; - - /* packet and buffer objects */ - struct emac_netpktobj pkt_queue; - struct emac_netbufobj buf_queue; - - /** statistics */ - u32 proc_count; /* number of times emac_rx_bdproc is called */ - u32 processed_bd; - u32 recycled_bd; - u32 out_of_rx_bd; - u32 out_of_rx_buffers; - u32 queue_reinit; - u32 end_of_queue_add; - u32 end_of_queue; - u32 mis_queued_packets; -}; - /* emac_priv: EMAC private data structure * * EMAC adapter private data structure @@ -452,17 +317,10 @@ struct emac_priv { struct platform_device *pdev; struct napi_struct napi; char mac_addr[6]; - spinlock_t tx_lock; - spinlock_t rx_lock; void __iomem *remap_addr; u32 emac_base_phys; void __iomem *emac_base; void __iomem *ctrl_base; - void __iomem *emac_ctrl_ram; - u32 ctrl_ram_size; - u32 hw_ram_addr; - struct emac_txch *txch[EMAC_DEF_MAX_TX_CH]; - struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH]; struct cpdma_ctlr *dma; struct cpdma_chan *txchan; struct cpdma_chan *rxchan; @@ -491,18 +349,6 @@ struct emac_priv { static struct clk *emac_clk; static unsigned long emac_bus_frequency; -#define emac_virt_to_phys(addr, priv) \ - (((u32 __force)(addr) - (u32 __force)(priv->emac_ctrl_ram)) \ - + priv->hw_ram_addr) - -/* Cache macros - Packet buffers would be from skb pool which is cached */ -#define EMAC_VIRT_NOCACHE(addr) (addr) - -/* DM644x does not have BD's in cached memory - so no cache functions */ -#define BD_CACHE_INVALIDATE(addr, size) -#define BD_CACHE_WRITEBACK(addr, size) -#define BD_CACHE_WRITEBACK_INVALIDATE(addr, size) - /* EMAC TX Host Error description strings */ static char *emac_txhost_errcodes[16] = { "No error", "SOP error", "Ownership bit not set in SOP buffer", @@ -545,20 +391,6 @@ static void emac_dump_regs(struct emac_priv *priv) emac_ctrl_read(EMAC_CTRL_EWCTL), emac_ctrl_read(EMAC_CTRL_EWINTTCNT)); } - dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n", - emac_read(EMAC_TXIDVER), - ((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"), - emac_read(EMAC_RXIDVER), - ((emac_read(EMAC_RXCONTROL)) ? "enabled" : "disabled")); - dev_info(emac_dev, "EMAC: TXIntRaw:%08X, TxIntMasked: %08X, "\ - "TxIntMasSet: %08X\n", emac_read(EMAC_TXINTSTATRAW), - emac_read(EMAC_TXINTSTATMASKED), emac_read(EMAC_TXINTMASKSET)); - dev_info(emac_dev, "EMAC: RXIntRaw:%08X, RxIntMasked: %08X, "\ - "RxIntMasSet: %08X\n", emac_read(EMAC_RXINTSTATRAW), - emac_read(EMAC_RXINTSTATMASKED), emac_read(EMAC_RXINTMASKSET)); - dev_info(emac_dev, "EMAC: MacIntRaw:%08X, MacIntMasked: %08X, "\ - "MacInVector=%08X\n", emac_read(EMAC_MACINTSTATRAW), - emac_read(EMAC_MACINTSTATMASKED), emac_read(EMAC_MACINVECTOR)); dev_info(emac_dev, "EMAC: EmuControl:%08X, FifoControl: %08X\n", emac_read(EMAC_EMCONTROL), emac_read(EMAC_FIFOCONTROL)); dev_info(emac_dev, "EMAC: MBPEnable:%08X, RXUnicastSet: %08X, "\ @@ -567,8 +399,6 @@ static void emac_dump_regs(struct emac_priv *priv) dev_info(emac_dev, "EMAC: MacControl:%08X, MacStatus: %08X, "\ "MacConfig=%08X\n", emac_read(EMAC_MACCONTROL), emac_read(EMAC_MACSTATUS), emac_read(EMAC_MACCONFIG)); - dev_info(emac_dev, "EMAC: TXHDP[0]:%08X, RXHDP[0]: %08X\n", - emac_read(EMAC_TXHDP(0)), emac_read(EMAC_RXHDP(0))); dev_info(emac_dev, "EMAC Statistics\n"); dev_info(emac_dev, "EMAC: rx_good_frames:%d\n", emac_read(EMAC_RXGOODFRAMES)); @@ -1223,373 +1053,6 @@ static void emac_tx_handler(void *token, int len, int status) dev_kfree_skb_any(skb); } -/** EMAC on-chip buffer descriptor memory - * - * WARNING: Please note that the on chip memory is used for both TX and RX - * buffer descriptor queues and is equally divided between TX and RX desc's - * If the number of TX or RX descriptors change this memory pointers need - * to be adjusted. If external memory is allocated then these pointers can - * pointer to the memory - * - */ -#define EMAC_TX_BD_MEM(priv) ((priv)->emac_ctrl_ram) -#define EMAC_RX_BD_MEM(priv) ((priv)->emac_ctrl_ram + \ - (((priv)->ctrl_ram_size) >> 1)) - -/** - * emac_init_txch: TX channel initialization - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number - * - * Called during device init to setup a TX channel (allocate buffer desc - * create free pool and keep ready for transmission - * - * Returns success(0) or mem alloc failures error code - */ -static int emac_init_txch(struct emac_priv *priv, u32 ch) -{ - struct device *emac_dev = &priv->ndev->dev; - u32 cnt, bd_size; - void __iomem *mem; - struct emac_tx_bd __iomem *curr_bd; - struct emac_txch *txch = NULL; - - txch = kzalloc(sizeof(struct emac_txch), GFP_KERNEL); - if (NULL == txch) { - dev_err(emac_dev, "DaVinci EMAC: TX Ch mem alloc failed"); - return -ENOMEM; - } - priv->txch[ch] = txch; - txch->service_max = EMAC_DEF_TX_MAX_SERVICE; - txch->active_queue_head = NULL; - txch->active_queue_tail = NULL; - txch->queue_active = 0; - txch->teardown_pending = 0; - - /* allocate memory for TX CPPI channel on a 4 byte boundry */ - txch->tx_complete = kzalloc(txch->service_max * sizeof(u32), - GFP_KERNEL); - if (NULL == txch->tx_complete) { - dev_err(emac_dev, "DaVinci EMAC: Tx service mem alloc failed"); - kfree(txch); - return -ENOMEM; - } - - /* allocate buffer descriptor pool align every BD on four word - * boundry for future requirements */ - bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF; - txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size; - txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF); - - /* alloc TX BD memory */ - txch->bd_mem = EMAC_TX_BD_MEM(priv); - __memzero((void __force *)txch->bd_mem, txch->alloc_size); - - /* initialize the BD linked list */ - mem = (void __force __iomem *) - (((u32 __force) txch->bd_mem + 0xF) & ~0xF); - txch->bd_pool_head = NULL; - for (cnt = 0; cnt < txch->num_bd; cnt++) { - curr_bd = mem + (cnt * bd_size); - curr_bd->next = txch->bd_pool_head; - txch->bd_pool_head = curr_bd; - } - - /* reset statistics counters */ - txch->out_of_tx_bd = 0; - txch->no_active_pkts = 0; - txch->active_queue_count = 0; - - return 0; -} - -/** - * emac_cleanup_txch: Book-keep function to clean TX channel resources - * @priv: The DaVinci EMAC private adapter structure - * @ch: TX channel number - * - * Called to clean up TX channel resources - * - */ -static void emac_cleanup_txch(struct emac_priv *priv, u32 ch) -{ - struct emac_txch *txch = priv->txch[ch]; - - if (txch) { - if (txch->bd_mem) - txch->bd_mem = NULL; - kfree(txch->tx_complete); - kfree(txch); - priv->txch[ch] = NULL; - } -} - -/** - * emac_net_tx_complete: TX packet completion function - * @priv: The DaVinci EMAC private adapter structure - * @net_data_tokens: packet token - skb pointer - * @num_tokens: number of skb's to free - * @ch: TX channel number - * - * Frees the skb once packet is transmitted - * - */ -static int emac_net_tx_complete(struct emac_priv *priv, - void **net_data_tokens, - int num_tokens, u32 ch) -{ - struct net_device *ndev = priv->ndev; - u32 cnt; - - if (unlikely(num_tokens && netif_queue_stopped(ndev))) - netif_start_queue(ndev); - for (cnt = 0; cnt < num_tokens; cnt++) { - struct sk_buff *skb = (struct sk_buff *)net_data_tokens[cnt]; - if (skb == NULL) - continue; - ndev->stats.tx_packets++; - ndev->stats.tx_bytes += skb->len; - dev_kfree_skb_any(skb); - } - return 0; -} - -/** - * emac_txch_teardown: TX channel teardown - * @priv: The DaVinci EMAC private adapter structure - * @ch: TX channel number - * - * Called to teardown TX channel - * - */ -static void emac_txch_teardown(struct emac_priv *priv, u32 ch) -{ - struct device *emac_dev = &priv->ndev->dev; - u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */ - struct emac_txch *txch = priv->txch[ch]; - struct emac_tx_bd __iomem *curr_bd; - - while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) != - EMAC_TEARDOWN_VALUE) { - /* wait till tx teardown complete */ - cpu_relax(); /* TODO: check if this helps ... */ - --teardown_cnt; - if (0 == teardown_cnt) { - dev_err(emac_dev, "EMAC: TX teardown aborted\n"); - break; - } - } - emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE); - - /* process sent packets and return skb's to upper layer */ - if (1 == txch->queue_active) { - curr_bd = txch->active_queue_head; - while (curr_bd != NULL) { - dma_unmap_single(emac_dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_TO_DEVICE); - - emac_net_tx_complete(priv, (void __force *) - &curr_bd->buf_token, 1, ch); - if (curr_bd != txch->active_queue_tail) - curr_bd = curr_bd->next; - else - break; - } - txch->bd_pool_head = txch->active_queue_head; - txch->active_queue_head = - txch->active_queue_tail = NULL; - } -} - -/** - * emac_stop_txch: Stop TX channel operation - * @priv: The DaVinci EMAC private adapter structure - * @ch: TX channel number - * - * Called to stop TX channel operation - * - */ -static void emac_stop_txch(struct emac_priv *priv, u32 ch) -{ - struct emac_txch *txch = priv->txch[ch]; - - if (txch) { - txch->teardown_pending = 1; - emac_write(EMAC_TXTEARDOWN, 0); - emac_txch_teardown(priv, ch); - txch->teardown_pending = 0; - emac_write(EMAC_TXINTMASKCLEAR, BIT(ch)); - } -} - -/** - * emac_tx_bdproc: TX buffer descriptor (packet) processing - * @priv: The DaVinci EMAC private adapter structure - * @ch: TX channel number to process buffer descriptors for - * @budget: number of packets allowed to process - * @pending: indication to caller that packets are pending to process - * - * Processes TX buffer descriptors after packets are transmitted - checks - * ownership bit on the TX * descriptor and requeues it to free pool & frees - * the SKB buffer. Only "budget" number of packets are processed and - * indication of pending packets provided to the caller - * - * Returns number of packets processed - */ -static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) -{ - struct device *emac_dev = &priv->ndev->dev; - unsigned long flags; - u32 frame_status; - u32 pkts_processed = 0; - u32 tx_complete_cnt = 0; - struct emac_tx_bd __iomem *curr_bd; - struct emac_txch *txch = priv->txch[ch]; - u32 *tx_complete_ptr = txch->tx_complete; - - if (unlikely(1 == txch->teardown_pending)) { - if (netif_msg_tx_err(priv) && net_ratelimit()) { - dev_err(emac_dev, "DaVinci EMAC:emac_tx_bdproc: "\ - "teardown pending\n"); - } - return 0; /* dont handle any pkt completions */ - } - - ++txch->proc_count; - spin_lock_irqsave(&priv->tx_lock, flags); - curr_bd = txch->active_queue_head; - if (NULL == curr_bd) { - emac_write(EMAC_TXCP(ch), - emac_virt_to_phys(txch->last_hw_bdprocessed, priv)); - txch->no_active_pkts++; - spin_unlock_irqrestore(&priv->tx_lock, flags); - return 0; - } - BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - frame_status = curr_bd->mode; - while ((curr_bd) && - ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && - (pkts_processed < budget)) { - emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd, priv)); - txch->active_queue_head = curr_bd->next; - if (frame_status & EMAC_CPPI_EOQ_BIT) { - if (curr_bd->next) { /* misqueued packet */ - emac_write(EMAC_TXHDP(ch), curr_bd->h_next); - ++txch->mis_queued_packets; - } else { - txch->queue_active = 0; /* end of queue */ - } - } - - dma_unmap_single(emac_dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_TO_DEVICE); - - *tx_complete_ptr = (u32) curr_bd->buf_token; - ++tx_complete_ptr; - ++tx_complete_cnt; - curr_bd->next = txch->bd_pool_head; - txch->bd_pool_head = curr_bd; - --txch->active_queue_count; - pkts_processed++; - txch->last_hw_bdprocessed = curr_bd; - curr_bd = txch->active_queue_head; - if (curr_bd) { - BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - frame_status = curr_bd->mode; - } - } /* end of pkt processing loop */ - - emac_net_tx_complete(priv, - (void *)&txch->tx_complete[0], - tx_complete_cnt, ch); - spin_unlock_irqrestore(&priv->tx_lock, flags); - return pkts_processed; -} - -#define EMAC_ERR_TX_OUT_OF_BD -1 - -/** - * emac_send: EMAC Transmit function (internal) - * @priv: The DaVinci EMAC private adapter structure - * @pkt: packet pointer (contains skb ptr) - * @ch: TX channel number - * - * Called by the transmit function to queue the packet in EMAC hardware queue - * - * Returns success(0) or error code (typically out of desc's) - */ -static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch) -{ - unsigned long flags; - struct emac_tx_bd __iomem *curr_bd; - struct emac_txch *txch; - struct emac_netbufobj *buf_list; - - txch = priv->txch[ch]; - buf_list = pkt->buf_list; /* get handle to the buffer array */ - - /* check packet size and pad if short */ - if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) { - buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length); - pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE; - } - - spin_lock_irqsave(&priv->tx_lock, flags); - curr_bd = txch->bd_pool_head; - if (curr_bd == NULL) { - txch->out_of_tx_bd++; - spin_unlock_irqrestore(&priv->tx_lock, flags); - return EMAC_ERR_TX_OUT_OF_BD; - } - - txch->bd_pool_head = curr_bd->next; - curr_bd->buf_token = buf_list->buf_token; - curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr, - buf_list->length, DMA_TO_DEVICE); - curr_bd->off_b_len = buf_list->length; - curr_bd->h_next = 0; - curr_bd->next = NULL; - curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT | - EMAC_CPPI_EOP_BIT | pkt->pkt_length); - - /* flush the packet from cache if write back cache is present */ - BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - - /* send the packet */ - if (txch->active_queue_head == NULL) { - txch->active_queue_head = curr_bd; - txch->active_queue_tail = curr_bd; - if (1 != txch->queue_active) { - emac_write(EMAC_TXHDP(ch), - emac_virt_to_phys(curr_bd, priv)); - txch->queue_active = 1; - } - ++txch->queue_reinit; - } else { - register struct emac_tx_bd __iomem *tail_bd; - register u32 frame_status; - - tail_bd = txch->active_queue_tail; - tail_bd->next = curr_bd; - txch->active_queue_tail = curr_bd; - tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = (int)emac_virt_to_phys(curr_bd, priv); - frame_status = tail_bd->mode; - if (frame_status & EMAC_CPPI_EOQ_BIT) { - emac_write(EMAC_TXHDP(ch), - emac_virt_to_phys(curr_bd, priv)); - frame_status &= ~(EMAC_CPPI_EOQ_BIT); - tail_bd->mode = frame_status; - ++txch->end_of_queue_add; - } - } - txch->active_queue_count++; - spin_unlock_irqrestore(&priv->tx_lock, flags); - return 0; -} - /** * emac_dev_xmit: EMAC Transmit function * @skb: SKB pointer @@ -1664,207 +1127,6 @@ static void emac_dev_tx_timeout(struct net_device *ndev) } /** - * emac_net_alloc_rx_buf: Allocate a skb for RX - * @priv: The DaVinci EMAC private adapter structure - * @buf_size: size of SKB data buffer to allocate - * @data_token: data token returned (skb handle for storing in buffer desc) - * @ch: RX channel number - * - * Called during RX channel setup - allocates skb buffer of required size - * and provides the skb handle and allocated buffer data pointer to caller - * - * Returns skb data pointer or 0 on failure to alloc skb - */ -static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size, - void **data_token, u32 ch) -{ - struct net_device *ndev = priv->ndev; - struct device *emac_dev = &ndev->dev; - struct sk_buff *p_skb; - - p_skb = dev_alloc_skb(buf_size); - if (unlikely(NULL == p_skb)) { - if (netif_msg_rx_err(priv) && net_ratelimit()) - dev_err(emac_dev, "DaVinci EMAC: failed to alloc skb"); - return NULL; - } - - /* set device pointer in skb and reserve space for extra bytes */ - p_skb->dev = ndev; - skb_reserve(p_skb, NET_IP_ALIGN); - *data_token = (void *) p_skb; - return p_skb->data; -} - -/** - * emac_init_rxch: RX channel initialization - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number - * @param: mac address for RX channel - * - * Called during device init to setup a RX channel (allocate buffers and - * buffer descriptors, create queue and keep ready for reception - * - * Returns success(0) or mem alloc failures error code - */ -static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param) -{ - struct device *emac_dev = &priv->ndev->dev; - u32 cnt, bd_size; - void __iomem *mem; - struct emac_rx_bd __iomem *curr_bd; - struct emac_rxch *rxch = NULL; - - rxch = kzalloc(sizeof(struct emac_rxch), GFP_KERNEL); - if (NULL == rxch) { - dev_err(emac_dev, "DaVinci EMAC: RX Ch mem alloc failed"); - return -ENOMEM; - } - priv->rxch[ch] = rxch; - rxch->buf_size = priv->rx_buf_size; - rxch->service_max = EMAC_DEF_RX_MAX_SERVICE; - rxch->queue_active = 0; - rxch->teardown_pending = 0; - - /* save mac address */ - for (cnt = 0; cnt < 6; cnt++) - rxch->mac_addr[cnt] = param[cnt]; - - /* allocate buffer descriptor pool align every BD on four word - * boundry for future requirements */ - bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF; - rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size; - rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF); - rxch->bd_mem = EMAC_RX_BD_MEM(priv); - __memzero((void __force *)rxch->bd_mem, rxch->alloc_size); - rxch->pkt_queue.buf_list = &rxch->buf_queue; - - /* allocate RX buffer and initialize the BD linked list */ - mem = (void __force __iomem *) - (((u32 __force) rxch->bd_mem + 0xF) & ~0xF); - rxch->active_queue_head = NULL; - rxch->active_queue_tail = mem; - for (cnt = 0; cnt < rxch->num_bd; cnt++) { - curr_bd = mem + (cnt * bd_size); - /* for future use the last parameter contains the BD ptr */ - curr_bd->data_ptr = emac_net_alloc_rx_buf(priv, - rxch->buf_size, - (void __force **)&curr_bd->buf_token, - EMAC_DEF_RX_CH); - if (curr_bd->data_ptr == NULL) { - dev_err(emac_dev, "DaVinci EMAC: RX buf mem alloc " \ - "failed for ch %d\n", ch); - kfree(rxch); - return -ENOMEM; - } - - /* populate the hardware descriptor */ - curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head, - priv); - curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr, - rxch->buf_size, DMA_FROM_DEVICE); - curr_bd->off_b_len = rxch->buf_size; - curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; - - /* write back to hardware memory */ - BD_CACHE_WRITEBACK_INVALIDATE((u32) curr_bd, - EMAC_BD_LENGTH_FOR_CACHE); - curr_bd->next = rxch->active_queue_head; - rxch->active_queue_head = curr_bd; - } - - /* At this point rxCppi->activeQueueHead points to the first - RX BD ready to be given to RX HDP and rxch->active_queue_tail - points to the last RX BD - */ - return 0; -} - -/** - * emac_rxch_teardown: RX channel teardown - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number - * - * Called during device stop to teardown RX channel - * - */ -static void emac_rxch_teardown(struct emac_priv *priv, u32 ch) -{ - struct device *emac_dev = &priv->ndev->dev; - u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */ - - while ((emac_read(EMAC_RXCP(ch)) & EMAC_TEARDOWN_VALUE) != - EMAC_TEARDOWN_VALUE) { - /* wait till tx teardown complete */ - cpu_relax(); /* TODO: check if this helps ... */ - --teardown_cnt; - if (0 == teardown_cnt) { - dev_err(emac_dev, "EMAC: RX teardown aborted\n"); - break; - } - } - emac_write(EMAC_RXCP(ch), EMAC_TEARDOWN_VALUE); -} - -/** - * emac_stop_rxch: Stop RX channel operation - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number - * - * Called during device stop to stop RX channel operation - * - */ -static void emac_stop_rxch(struct emac_priv *priv, u32 ch) -{ - struct emac_rxch *rxch = priv->rxch[ch]; - - if (rxch) { - rxch->teardown_pending = 1; - emac_write(EMAC_RXTEARDOWN, ch); - /* wait for teardown complete */ - emac_rxch_teardown(priv, ch); - rxch->teardown_pending = 0; - emac_write(EMAC_RXINTMASKCLEAR, BIT(ch)); - } -} - -/** - * emac_cleanup_rxch: Book-keep function to clean RX channel resources - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number - * - * Called during device stop to clean up RX channel resources - * - */ -static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch) -{ - struct emac_rxch *rxch = priv->rxch[ch]; - struct emac_rx_bd __iomem *curr_bd; - - if (rxch) { - /* free the receive buffers previously allocated */ - curr_bd = rxch->active_queue_head; - while (curr_bd) { - if (curr_bd->buf_token) { - dma_unmap_single(&priv->ndev->dev, - curr_bd->buff_ptr, - curr_bd->off_b_len - & EMAC_RX_BD_BUF_SIZE, - DMA_FROM_DEVICE); - - dev_kfree_skb_any((struct sk_buff *)\ - curr_bd->buf_token); - } - curr_bd = curr_bd->next; - } - if (rxch->bd_mem) - rxch->bd_mem = NULL; - kfree(rxch); - priv->rxch[ch] = NULL; - } -} - -/** * emac_set_type0addr: Set EMAC Type0 mac address * @priv: The DaVinci EMAC private adapter structure * @ch: RX channel number @@ -2004,194 +1266,6 @@ static int emac_dev_setmac_addr(struct net_device *ndev, void *addr) } /** - * emac_addbd_to_rx_queue: Recycle RX buffer descriptor - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number to process buffer descriptors for - * @curr_bd: current buffer descriptor - * @buffer: buffer pointer for descriptor - * @buf_token: buffer token (stores skb information) - * - * Prepares the recycled buffer descriptor and addes it to hardware - * receive queue - if queue empty this descriptor becomes the head - * else addes the descriptor to end of queue - * - */ -static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch, - struct emac_rx_bd __iomem *curr_bd, - char *buffer, void *buf_token) -{ - struct emac_rxch *rxch = priv->rxch[ch]; - - /* populate the hardware descriptor */ - curr_bd->h_next = 0; - curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer, - rxch->buf_size, DMA_FROM_DEVICE); - curr_bd->off_b_len = rxch->buf_size; - curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT; - curr_bd->next = NULL; - curr_bd->data_ptr = buffer; - curr_bd->buf_token = buf_token; - - /* write back */ - BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - if (rxch->active_queue_head == NULL) { - rxch->active_queue_head = curr_bd; - rxch->active_queue_tail = curr_bd; - if (0 != rxch->queue_active) { - emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(rxch->active_queue_head, priv)); - rxch->queue_active = 1; - } - } else { - struct emac_rx_bd __iomem *tail_bd; - u32 frame_status; - - tail_bd = rxch->active_queue_tail; - rxch->active_queue_tail = curr_bd; - tail_bd->next = curr_bd; - tail_bd = EMAC_VIRT_NOCACHE(tail_bd); - tail_bd->h_next = emac_virt_to_phys(curr_bd, priv); - frame_status = tail_bd->mode; - if (frame_status & EMAC_CPPI_EOQ_BIT) { - emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd, priv)); - frame_status &= ~(EMAC_CPPI_EOQ_BIT); - tail_bd->mode = frame_status; - ++rxch->end_of_queue_add; - } - } - ++rxch->recycled_bd; -} - -/** - * emac_net_rx_cb: Prepares packet and sends to upper layer - * @priv: The DaVinci EMAC private adapter structure - * @net_pkt_list: Network packet list (received packets) - * - * Invalidates packet buffer memory and sends the received packet to upper - * layer - * - * Returns success or appropriate error code (none as of now) - */ -static int emac_net_rx_cb(struct emac_priv *priv, - struct emac_netpktobj *net_pkt_list) -{ - struct net_device *ndev = priv->ndev; - struct sk_buff *p_skb = net_pkt_list->pkt_token; - /* set length of packet */ - skb_put(p_skb, net_pkt_list->pkt_length); - p_skb->protocol = eth_type_trans(p_skb, priv->ndev); - netif_receive_skb(p_skb); - ndev->stats.rx_bytes += net_pkt_list->pkt_length; - ndev->stats.rx_packets++; - return 0; -} - -/** - * emac_rx_bdproc: RX buffer descriptor (packet) processing - * @priv: The DaVinci EMAC private adapter structure - * @ch: RX channel number to process buffer descriptors for - * @budget: number of packets allowed to process - * @pending: indication to caller that packets are pending to process - * - * Processes RX buffer descriptors - checks ownership bit on the RX buffer - * descriptor, sends the receive packet to upper layer, allocates a new SKB - * and recycles the buffer descriptor (requeues it in hardware RX queue). - * Only "budget" number of packets are processed and indication of pending - * packets provided to the caller. - * - * Returns number of packets processed (and indication of pending packets) - */ -static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget) -{ - unsigned long flags; - u32 frame_status; - u32 pkts_processed = 0; - char *new_buffer; - struct emac_rx_bd __iomem *curr_bd; - struct emac_rx_bd __iomem *last_bd; - struct emac_netpktobj *curr_pkt, pkt_obj; - struct emac_netbufobj buf_obj; - struct emac_netbufobj *rx_buf_obj; - void *new_buf_token; - struct emac_rxch *rxch = priv->rxch[ch]; - - if (unlikely(1 == rxch->teardown_pending)) - return 0; - ++rxch->proc_count; - spin_lock_irqsave(&priv->rx_lock, flags); - pkt_obj.buf_list = &buf_obj; - curr_pkt = &pkt_obj; - curr_bd = rxch->active_queue_head; - BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - frame_status = curr_bd->mode; - - while ((curr_bd) && - ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) && - (pkts_processed < budget)) { - - new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size, - &new_buf_token, EMAC_DEF_RX_CH); - if (unlikely(NULL == new_buffer)) { - ++rxch->out_of_rx_buffers; - goto end_emac_rx_bdproc; - } - - /* populate received packet data structure */ - rx_buf_obj = &curr_pkt->buf_list[0]; - rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr; - rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE; - rx_buf_obj->buf_token = curr_bd->buf_token; - - dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr, - curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE, - DMA_FROM_DEVICE); - - curr_pkt->pkt_token = curr_pkt->buf_list->buf_token; - curr_pkt->num_bufs = 1; - curr_pkt->pkt_length = - (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK); - emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd, priv)); - ++rxch->processed_bd; - last_bd = curr_bd; - curr_bd = last_bd->next; - rxch->active_queue_head = curr_bd; - - /* check if end of RX queue ? */ - if (frame_status & EMAC_CPPI_EOQ_BIT) { - if (curr_bd) { - ++rxch->mis_queued_packets; - emac_write(EMAC_RXHDP(ch), - emac_virt_to_phys(curr_bd, priv)); - } else { - ++rxch->end_of_queue; - rxch->queue_active = 0; - } - } - - /* recycle BD */ - emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer, - new_buf_token); - - /* return the packet to the user - BD ptr passed in - * last parameter for potential *future* use */ - spin_unlock_irqrestore(&priv->rx_lock, flags); - emac_net_rx_cb(priv, curr_pkt); - spin_lock_irqsave(&priv->rx_lock, flags); - curr_bd = rxch->active_queue_head; - if (curr_bd) { - BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE); - frame_status = curr_bd->mode; - } - ++pkts_processed; - } - -end_emac_rx_bdproc: - spin_unlock_irqrestore(&priv->rx_lock, flags); - return pkts_processed; -} - -/** * emac_hw_enable: Enable EMAC hardware for packet transmission/reception * @priv: The DaVinci EMAC private adapter structure * @@ -2717,8 +1791,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) priv->ndev = ndev; priv->msg_enable = netif_msg_init(debug_level, DAVINCI_EMAC_DEBUG); - spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->rx_lock); spin_lock_init(&priv->lock); pdata = pdev->dev.platform_data; @@ -2766,8 +1838,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) ndev->base_addr = (unsigned long)priv->remap_addr; priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset; - priv->ctrl_ram_size = pdata->ctrl_ram_size; - priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset; hw_ram_addr = pdata->hw_ram_addr; if (!hw_ram_addr) -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:05 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:05 -0700 Subject: [PATCH 41/47] input: add driver for tnetv107x on-chip keypad controller In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-42-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds support for tnetv107x's on-chip keypad controller. Signed-off-by: Cyril Chemparathy Acked-by: Dmitry Torokhov Signed-off-by: Kevin Hilman --- drivers/input/keyboard/Kconfig | 9 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/tnetv107x-keypad.c | 340 +++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 0 deletions(-) create mode 100644 drivers/input/keyboard/tnetv107x-keypad.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 9cc488d..df1facb 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -424,6 +424,15 @@ config KEYBOARD_OMAP To compile this driver as a module, choose M here: the module will be called omap-keypad. +config KEYBOARD_TNETV107X + tristate "TI TNETV107X keypad support" + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here if you want to use the TNETV107X keypad. + + To compile this driver as a module, choose M here: the + module will be called tnetv107x-keypad. + config KEYBOARD_TWL4030 tristate "TI TWL4030/TWL5030/TPS659x0 keypad support" depends on TWL4030_CORE diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 504b591..dc04518 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o +obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c new file mode 100644 index 0000000..b4a81eb --- /dev/null +++ b/drivers/input/keyboard/tnetv107x-keypad.c @@ -0,0 +1,340 @@ +/* + * Texas Instruments TNETV107X Keypad Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BITS(x) (BIT(x) - 1) + +#define KEYPAD_ROWS 9 +#define KEYPAD_COLS 9 + +#define DEBOUNCE_MIN 0x400ul +#define DEBOUNCE_MAX 0x3ffffffful + +struct keypad_regs { + u32 rev; + u32 mode; + u32 mask; + u32 pol; + u32 dclock; + u32 rclock; + u32 stable_cnt; + u32 in_en; + u32 out; + u32 out_en; + u32 in; + u32 lock; + u32 pres[3]; +}; + +#define keypad_read(kp, reg) __raw_readl(&(kp)->regs->reg) +#define keypad_write(kp, reg, val) __raw_writel(val, &(kp)->regs->reg) + +struct keypad_data { + struct input_dev *input_dev; + struct resource *res; + struct keypad_regs __iomem *regs; + struct clk *clk; + struct device *dev; + spinlock_t lock; + u32 irq_press; + u32 irq_release; + int rows, cols, row_shift; + int debounce_ms, active_low; + u32 prev_keys[3]; + unsigned short keycodes[]; +}; + +static irqreturn_t keypad_irq(int irq, void *data) +{ + struct keypad_data *kp = data; + int i, bit, val, row, col, code; + unsigned long flags; + u32 curr_keys[3]; + u32 change; + + spin_lock_irqsave(&kp->lock, flags); + + memset(curr_keys, 0, sizeof(curr_keys)); + if (irq == kp->irq_press) + for (i = 0; i < 3; i++) + curr_keys[i] = keypad_read(kp, pres[i]); + + for (i = 0; i < 3; i++) { + change = curr_keys[i] ^ kp->prev_keys[i]; + + while (change) { + bit = fls(change) - 1; + change ^= BIT(bit); + val = curr_keys[i] & BIT(bit); + bit += i * 32; + row = bit / KEYPAD_COLS; + col = bit % KEYPAD_COLS; + + code = MATRIX_SCAN_CODE(row, col, kp->row_shift); + input_event(kp->input_dev, EV_MSC, MSC_SCAN, code); + input_report_key(kp->input_dev, kp->keycodes[code], + val); + } + } + input_sync(kp->input_dev); + memcpy(kp->prev_keys, curr_keys, sizeof(curr_keys)); + + if (irq == kp->irq_press) + keypad_write(kp, lock, 0); /* Allow hardware updates */ + + spin_unlock_irqrestore(&kp->lock, flags); + + return IRQ_HANDLED; +} + +static int keypad_start(struct input_dev *dev) +{ + struct keypad_data *kp = input_get_drvdata(dev); + unsigned long mask, debounce, clk_rate_khz; + unsigned long flags; + + clk_enable(kp->clk); + clk_rate_khz = clk_get_rate(kp->clk) / 1000; + + spin_lock_irqsave(&kp->lock, flags); + + /* Initialize device registers */ + keypad_write(kp, mode, 0); + + mask = BITS(kp->rows) << KEYPAD_COLS; + mask |= BITS(kp->cols); + keypad_write(kp, mask, ~mask); + + keypad_write(kp, pol, kp->active_low ? 0 : 0x3ffff); + keypad_write(kp, stable_cnt, 3); + + debounce = kp->debounce_ms * clk_rate_khz; + debounce = clamp(debounce, DEBOUNCE_MIN, DEBOUNCE_MAX); + keypad_write(kp, dclock, debounce); + keypad_write(kp, rclock, 4 * debounce); + + keypad_write(kp, in_en, 1); + + spin_unlock_irqrestore(&kp->lock, flags); + + return 0; +} + +static void keypad_stop(struct input_dev *dev) +{ + struct keypad_data *kp = input_get_drvdata(dev); + + synchronize_irq(kp->irq_press); + synchronize_irq(kp->irq_release); + clk_disable(kp->clk); +} + +static int __devinit keypad_probe(struct platform_device *pdev) +{ + const struct matrix_keypad_platform_data *pdata; + const struct matrix_keymap_data *keymap_data; + struct device *dev = &pdev->dev; + struct keypad_data *kp; + int error = 0, sz, row_shift; + u32 rev = 0; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(dev, "cannot find device data\n"); + return -EINVAL; + } + + keymap_data = pdata->keymap_data; + if (!keymap_data) { + dev_err(dev, "cannot find keymap data\n"); + return -EINVAL; + } + + row_shift = get_count_order(pdata->num_col_gpios); + sz = offsetof(struct keypad_data, keycodes); + sz += (pdata->num_row_gpios << row_shift) * sizeof(kp->keycodes[0]); + kp = kzalloc(sz, GFP_KERNEL); + if (!kp) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + kp->dev = dev; + kp->rows = pdata->num_row_gpios; + kp->cols = pdata->num_col_gpios; + kp->row_shift = row_shift; + platform_set_drvdata(pdev, kp); + spin_lock_init(&kp->lock); + + kp->irq_press = platform_get_irq_byname(pdev, "press"); + kp->irq_release = platform_get_irq_byname(pdev, "release"); + if (kp->irq_press < 0 || kp->irq_release < 0) { + dev_err(dev, "cannot determine device interrupts\n"); + error = -ENODEV; + goto error_res; + } + + kp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!kp->res) { + dev_err(dev, "cannot determine register area\n"); + error = -ENODEV; + goto error_res; + } + + if (!request_mem_region(kp->res->start, resource_size(kp->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + kp->res = NULL; + error = -EINVAL; + goto error_res; + } + + kp->regs = ioremap(kp->res->start, resource_size(kp->res)); + if (!kp->regs) { + dev_err(dev, "cannot map register memory\n"); + error = -ENOMEM; + goto error_map; + } + + kp->clk = clk_get(dev, NULL); + if (!kp->clk) { + dev_err(dev, "cannot claim device clock\n"); + error = -EINVAL; + goto error_clk; + } + + error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, + dev_name(dev), kp); + if (error < 0) { + dev_err(kp->dev, "Could not allocate keypad press key irq\n"); + goto error_irq_press; + } + + error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, + dev_name(dev), kp); + if (error < 0) { + dev_err(kp->dev, "Could not allocate keypad release key irq\n"); + goto error_irq_release; + } + + kp->input_dev = input_allocate_device(); + if (!kp->input_dev) { + dev_err(dev, "cannot allocate input device\n"); + error = -ENOMEM; + goto error_input; + } + input_set_drvdata(kp->input_dev, kp); + + kp->input_dev->name = pdev->name; + kp->input_dev->dev.parent = &pdev->dev; + kp->input_dev->open = keypad_start; + kp->input_dev->close = keypad_stop; + kp->input_dev->evbit[0] = BIT_MASK(EV_KEY); + if (!pdata->no_autorepeat) + kp->input_dev->evbit[0] |= BIT_MASK(EV_REP); + + clk_enable(kp->clk); + rev = keypad_read(kp, rev); + kp->input_dev->id.bustype = BUS_HOST; + kp->input_dev->id.product = ((rev >> 8) & 0x07); + kp->input_dev->id.version = ((rev >> 16) & 0xfff); + clk_disable(kp->clk); + + kp->input_dev->keycode = kp->keycodes; + kp->input_dev->keycodesize = sizeof(kp->keycodes[0]); + kp->input_dev->keycodemax = kp->rows << kp->row_shift; + + matrix_keypad_build_keymap(keymap_data, kp->row_shift, kp->keycodes, + kp->input_dev->keybit); + + input_set_capability(kp->input_dev, EV_MSC, MSC_SCAN); + + error = input_register_device(kp->input_dev); + if (error < 0) { + dev_err(dev, "Could not register input device\n"); + goto error_reg; + } + + return 0; + + +error_reg: + input_free_device(kp->input_dev); +error_input: + free_irq(kp->irq_release, kp); +error_irq_release: + free_irq(kp->irq_press, kp); +error_irq_press: + clk_put(kp->clk); +error_clk: + iounmap(kp->regs); +error_map: + release_mem_region(kp->res->start, resource_size(kp->res)); +error_res: + platform_set_drvdata(pdev, NULL); + kfree(kp); + return error; +} + +static int __devexit keypad_remove(struct platform_device *pdev) +{ + struct keypad_data *kp = platform_get_drvdata(pdev); + + free_irq(kp->irq_press, kp); + free_irq(kp->irq_release, kp); + input_unregister_device(kp->input_dev); + clk_put(kp->clk); + iounmap(kp->regs); + release_mem_region(kp->res->start, resource_size(kp->res)); + platform_set_drvdata(pdev, NULL); + kfree(kp); + + return 0; +} + +static struct platform_driver keypad_driver = { + .probe = keypad_probe, + .remove = __devexit_p(keypad_remove), + .driver.name = "tnetv107x-keypad", + .driver.owner = THIS_MODULE, +}; + +static int __init keypad_init(void) +{ + return platform_driver_register(&keypad_driver); +} + +static void __exit keypad_exit(void) +{ + platform_driver_unregister(&keypad_driver); +} + +module_init(keypad_init); +module_exit(keypad_exit); + +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_DESCRIPTION("TNETV107X Keypad Driver"); +MODULE_ALIAS("platform: tnetv107x-keypad"); +MODULE_LICENSE("GPL"); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:06 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:06 -0700 Subject: [PATCH 42/47] davinci: add tnetv107x keypad platform device In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-43-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds a platform device definition for tnetv107x's keypad controller. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices-tnetv107x.c | 30 ++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 3 ++ 2 files changed, 33 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 2718a3a9..086269f 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -33,6 +33,7 @@ #define TNETV107X_WDOG_BASE 0x08086700 #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 +#define TNETV107X_KEYPAD_BASE 0x08088a00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 @@ -298,6 +299,30 @@ static int __init nand_init(int chipsel, struct davinci_nand_pdata *data) return platform_device_register(pdev); } +static struct resource keypad_resources[] = { + { + .start = TNETV107X_KEYPAD_BASE, + .end = TNETV107X_KEYPAD_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_KEYPAD, + .flags = IORESOURCE_IRQ, + .name = "press", + }, + { + .start = IRQ_TNETV107X_KEYPAD_FREE, + .flags = IORESOURCE_IRQ, + .name = "release", + }, +}; + +static struct platform_device keypad_device = { + .name = "tnetv107x-keypad", + .num_resources = ARRAY_SIZE(keypad_resources), + .resource = keypad_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -317,4 +342,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) for (i = 0; i < 4; i++) if (info->nand_config[i]) nand_init(i, info->nand_config[i]); + + if (info->keypad_config) { + keypad_device.dev.platform_data = info->keypad_config; + platform_device_register(&keypad_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index c720647..5a681d8 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -33,6 +33,8 @@ #ifndef __ASSEMBLY__ #include +#include + #include #include #include @@ -41,6 +43,7 @@ struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ + struct matrix_keypad_platform_data *keypad_config; }; extern struct platform_device tnetv107x_wdt_device; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:07 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:07 -0700 Subject: [PATCH 43/47] davinci: add keypad config for tnetv107x evm board In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-44-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds evm board specific keymap definitions and controller configuration data for on-chip keypad controller on tnetv107x silicon. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 56 +++++++++++++++++++++++++++ 1 files changed, 56 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index fe2a9d9..5afa8fc 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -23,6 +23,9 @@ #include #include #include +#include +#include + #include #include @@ -141,10 +144,63 @@ static struct davinci_uart_config serial_config __initconst = { .enabled_uarts = BIT(1), }; +static const uint32_t keymap[] = { + KEY(0, 0, KEY_NUMERIC_1), + KEY(0, 1, KEY_NUMERIC_2), + KEY(0, 2, KEY_NUMERIC_3), + KEY(0, 3, KEY_FN_F1), + KEY(0, 4, KEY_MENU), + + KEY(1, 0, KEY_NUMERIC_4), + KEY(1, 1, KEY_NUMERIC_5), + KEY(1, 2, KEY_NUMERIC_6), + KEY(1, 3, KEY_UP), + KEY(1, 4, KEY_FN_F2), + + KEY(2, 0, KEY_NUMERIC_7), + KEY(2, 1, KEY_NUMERIC_8), + KEY(2, 2, KEY_NUMERIC_9), + KEY(2, 3, KEY_LEFT), + KEY(2, 4, KEY_ENTER), + + KEY(3, 0, KEY_NUMERIC_STAR), + KEY(3, 1, KEY_NUMERIC_0), + KEY(3, 2, KEY_NUMERIC_POUND), + KEY(3, 3, KEY_DOWN), + KEY(3, 4, KEY_RIGHT), + + KEY(4, 0, KEY_FN_F3), + KEY(4, 1, KEY_FN_F4), + KEY(4, 2, KEY_MUTE), + KEY(4, 3, KEY_HOME), + KEY(4, 4, KEY_BACK), + + KEY(5, 0, KEY_VOLUMEDOWN), + KEY(5, 1, KEY_VOLUMEUP), + KEY(5, 2, KEY_F1), + KEY(5, 3, KEY_F2), + KEY(5, 4, KEY_F3), +}; + +static const struct matrix_keymap_data keymap_data = { + .keymap = keymap, + .keymap_size = ARRAY_SIZE(keymap), +}; + +static struct matrix_keypad_platform_data keypad_config = { + .keymap_data = &keymap_data, + .num_row_gpios = 6, + .num_col_gpios = 5, + .debounce_ms = 0, /* minimum */ + .active_low = 0, /* pull up realization */ + .no_autorepeat = 0, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ + .keypad_config = &keypad_config, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:08 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:08 -0700 Subject: [PATCH 44/47] input: add driver for tnetv107x touchscreen controller In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-45-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds support for tnetv107x's on-chip touchscreen controller. Signed-off-by: Cyril Chemparathy Acked-by: Dmitry Torokhov Signed-off-by: Kevin Hilman --- drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tnetv107x-ts.c | 396 ++++++++++++++++++++++++++++++ 3 files changed, 406 insertions(+), 0 deletions(-) create mode 100644 drivers/input/touchscreen/tnetv107x-ts.c diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 0069d97..8d32028 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -328,6 +328,15 @@ config TOUCHSCREEN_MIGOR To compile this driver as a module, choose M here: the module will be called migor_ts. +config TOUCHSCREEN_TNETV107X + tristate "TI TNETV107X touchscreen support" + depends on ARCH_DAVINCI_TNETV107X + help + Say Y here if you want to use the TNETV107X touchscreen. + + To compile this driver as a module, choose M here: the + module will be called tnetv107x-ts. + config TOUCHSCREEN_TOUCHRIGHT tristate "Touchright serial touchscreen" select SERIO diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 28217e1..d41a964 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_QT602240) += qt602240_ts.o obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o obj-$(CONFIG_TOUCHSCREEN_STMPE) += stmpe-ts.o +obj-$(CONFIG_TOUCHSCREEN_TNETV107X) += tnetv107x-ts.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c new file mode 100644 index 0000000..cf1dba2 --- /dev/null +++ b/drivers/input/touchscreen/tnetv107x-ts.c @@ -0,0 +1,396 @@ +/* + * Texas Instruments TNETV107X Touchscreen Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define TSC_PENUP_POLL (HZ / 5) +#define IDLE_TIMEOUT 100 /* msec */ + +/* + * The first and last samples of a touch interval are usually garbage and need + * to be filtered out with these devices. The following definitions control + * the number of samples skipped. + */ +#define TSC_HEAD_SKIP 1 +#define TSC_TAIL_SKIP 1 +#define TSC_SKIP (TSC_HEAD_SKIP + TSC_TAIL_SKIP + 1) +#define TSC_SAMPLES (TSC_SKIP + 1) + +/* Register Offsets */ +struct tsc_regs { + u32 rev; + u32 tscm; + u32 bwcm; + u32 swc; + u32 adcchnl; + u32 adcdata; + u32 chval[4]; +}; + +/* TSC Mode Configuration Register (tscm) bits */ +#define WMODE BIT(0) +#define TSKIND BIT(1) +#define ZMEASURE_EN BIT(2) +#define IDLE BIT(3) +#define TSC_EN BIT(4) +#define STOP BIT(5) +#define ONE_SHOT BIT(6) +#define SINGLE BIT(7) +#define AVG BIT(8) +#define AVGNUM(x) (((x) & 0x03) << 9) +#define PVSTC(x) (((x) & 0x07) << 11) +#define PON BIT(14) +#define PONBG BIT(15) +#define AFERST BIT(16) + +/* ADC DATA Capture Register bits */ +#define DATA_VALID BIT(16) + +/* Register Access Macros */ +#define tsc_read(ts, reg) __raw_readl(&(ts)->regs->reg) +#define tsc_write(ts, reg, val) __raw_writel(val, &(ts)->regs->reg); +#define tsc_set_bits(ts, reg, val) \ + tsc_write(ts, reg, tsc_read(ts, reg) | (val)) +#define tsc_clr_bits(ts, reg, val) \ + tsc_write(ts, reg, tsc_read(ts, reg) & ~(val)) + +struct sample { + int x, y, p; +}; + +struct tsc_data { + struct input_dev *input_dev; + struct resource *res; + struct tsc_regs __iomem *regs; + struct timer_list timer; + spinlock_t lock; + struct clk *clk; + struct device *dev; + int sample_count; + struct sample samples[TSC_SAMPLES]; + int tsc_irq; +}; + +static int tsc_read_sample(struct tsc_data *ts, struct sample* sample) +{ + int x, y, z1, z2, t, p = 0; + u32 val; + + val = tsc_read(ts, chval[0]); + if (val & DATA_VALID) + x = val & 0xffff; + else + return -EINVAL; + + y = tsc_read(ts, chval[1]) & 0xffff; + z1 = tsc_read(ts, chval[2]) & 0xffff; + z2 = tsc_read(ts, chval[3]) & 0xffff; + + if (z1) { + t = ((600 * x) * (z2 - z1)); + p = t / (u32) (z1 << 12); + if (p < 0) + p = 0; + } + + sample->x = x; + sample->y = y; + sample->p = p; + + return 0; +} + +static void tsc_poll(unsigned long data) +{ + struct tsc_data *ts = (struct tsc_data *)data; + unsigned long flags; + int i, val, x, y, p; + + spin_lock_irqsave(&ts->lock, flags); + + if (ts->sample_count >= TSC_SKIP) { + input_report_abs(ts->input_dev, ABS_PRESSURE, 0); + input_report_key(ts->input_dev, BTN_TOUCH, 0); + input_sync(ts->input_dev); + } else if (ts->sample_count > 0) { + /* + * A touch event lasted less than our skip count. Salvage and + * report anyway. + */ + for (i = 0, val = 0; i < ts->sample_count; i++) + val += ts->samples[i].x; + x = val / ts->sample_count; + + for (i = 0, val = 0; i < ts->sample_count; i++) + val += ts->samples[i].y; + y = val / ts->sample_count; + + for (i = 0, val = 0; i < ts->sample_count; i++) + val += ts->samples[i].p; + p = val / ts->sample_count; + + input_report_abs(ts->input_dev, ABS_X, x); + input_report_abs(ts->input_dev, ABS_Y, y); + input_report_abs(ts->input_dev, ABS_PRESSURE, p); + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_sync(ts->input_dev); + } + + ts->sample_count = 0; + + spin_unlock_irqrestore(&ts->lock, flags); +} + +static irqreturn_t tsc_irq(int irq, void *dev_id) +{ + struct tsc_data *ts = (struct tsc_data *)dev_id; + struct sample *sample; + int index; + + spin_lock(&ts->lock); + + index = ts->sample_count % TSC_SAMPLES; + sample = &ts->samples[index]; + if (tsc_read_sample(ts, sample) < 0) + goto out; + + if (++ts->sample_count >= TSC_SKIP) { + index = (ts->sample_count - TSC_TAIL_SKIP - 1) % TSC_SAMPLES; + sample = &ts->samples[index]; + + input_report_abs(ts->input_dev, ABS_X, sample->x); + input_report_abs(ts->input_dev, ABS_Y, sample->y); + input_report_abs(ts->input_dev, ABS_PRESSURE, sample->p); + if (ts->sample_count == TSC_SKIP) + input_report_key(ts->input_dev, BTN_TOUCH, 1); + input_sync(ts->input_dev); + } + mod_timer(&ts->timer, jiffies + TSC_PENUP_POLL); +out: + spin_unlock(&ts->lock); + return IRQ_HANDLED; +} + +static int tsc_start(struct input_dev *dev) +{ + struct tsc_data *ts = input_get_drvdata(dev); + unsigned long timeout = jiffies + msecs_to_jiffies(IDLE_TIMEOUT); + u32 val; + + clk_enable(ts->clk); + + /* Go to idle mode, before any initialization */ + while (time_after(timeout, jiffies)) { + if (tsc_read(ts, tscm) & IDLE) + break; + } + + if (time_before(timeout, jiffies)) { + dev_warn(ts->dev, "timeout waiting for idle\n"); + clk_disable(ts->clk); + return -EIO; + } + + /* Configure TSC Control register*/ + val = (PONBG | PON | PVSTC(4) | ONE_SHOT | ZMEASURE_EN); + tsc_write(ts, tscm, val); + + /* Bring TSC out of reset: Clear AFE reset bit */ + val &= ~(AFERST); + tsc_write(ts, tscm, val); + + /* Configure all pins for hardware control*/ + tsc_write(ts, bwcm, 0); + + /* Finally enable the TSC */ + tsc_set_bits(ts, tscm, TSC_EN); + + return 0; +} + +static void tsc_stop(struct input_dev *dev) +{ + struct tsc_data *ts = input_get_drvdata(dev); + + tsc_clr_bits(ts, tscm, TSC_EN); + synchronize_irq(ts->tsc_irq); + del_timer_sync(&ts->timer); + clk_disable(ts->clk); +} + +static int __devinit tsc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tsc_data *ts; + int error = 0; + u32 rev = 0; + + ts = kzalloc(sizeof(struct tsc_data), GFP_KERNEL); + if (!ts) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + ts->dev = dev; + spin_lock_init(&ts->lock); + setup_timer(&ts->timer, tsc_poll, (unsigned long)ts); + platform_set_drvdata(pdev, ts); + + ts->tsc_irq = platform_get_irq(pdev, 0); + if (ts->tsc_irq < 0) { + dev_err(dev, "cannot determine device interrupt\n"); + error = -ENODEV; + goto error_res; + } + + ts->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ts->res) { + dev_err(dev, "cannot determine register area\n"); + error = -ENODEV; + goto error_res; + } + + if (!request_mem_region(ts->res->start, resource_size(ts->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + ts->res = NULL; + error = -EINVAL; + goto error_res; + } + + ts->regs = ioremap(ts->res->start, resource_size(ts->res)); + if (!ts->regs) { + dev_err(dev, "cannot map register memory\n"); + error = -ENOMEM; + goto error_map; + } + + ts->clk = clk_get(dev, NULL); + if (!ts->clk) { + dev_err(dev, "cannot claim device clock\n"); + error = -EINVAL; + goto error_clk; + } + + error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, + dev_name(dev), ts); + if (error < 0) { + dev_err(ts->dev, "Could not allocate ts irq\n"); + goto error_irq; + } + + ts->input_dev = input_allocate_device(); + if (!ts->input_dev) { + dev_err(dev, "cannot allocate input device\n"); + error = -ENOMEM; + goto error_input; + } + input_set_drvdata(ts->input_dev, ts); + + ts->input_dev->name = pdev->name; + ts->input_dev->id.bustype = BUS_HOST; + ts->input_dev->dev.parent = &pdev->dev; + ts->input_dev->open = tsc_start; + ts->input_dev->close = tsc_stop; + + clk_enable(ts->clk); + rev = tsc_read(ts, rev); + ts->input_dev->id.product = ((rev >> 8) & 0x07); + ts->input_dev->id.version = ((rev >> 16) & 0xfff); + clk_disable(ts->clk); + + __set_bit(EV_KEY, ts->input_dev->evbit); + __set_bit(EV_ABS, ts->input_dev->evbit); + __set_bit(BTN_TOUCH, ts->input_dev->keybit); + + input_set_abs_params(ts->input_dev, ABS_X, 0, 0xffff, 5, 0); + input_set_abs_params(ts->input_dev, ABS_Y, 0, 0xffff, 5, 0); + input_set_abs_params(ts->input_dev, ABS_PRESSURE, 0, 4095, 128, 0); + + error = input_register_device(ts->input_dev); + if (error < 0) { + dev_err(dev, "failed input device registration\n"); + goto error_reg; + } + + return 0; + +error_reg: + input_free_device(ts->input_dev); +error_input: + free_irq(ts->tsc_irq, ts); +error_irq: + clk_put(ts->clk); +error_clk: + iounmap(ts->regs); +error_map: + release_mem_region(ts->res->start, resource_size(ts->res)); +error_res: + platform_set_drvdata(pdev, NULL); + kfree(ts); + + return error; +} + +static int __devexit tsc_remove(struct platform_device *pdev) +{ + struct tsc_data *ts = platform_get_drvdata(pdev); + + input_unregister_device(ts->input_dev); + free_irq(ts->tsc_irq, ts); + clk_put(ts->clk); + iounmap(ts->regs); + release_mem_region(ts->res->start, resource_size(ts->res)); + platform_set_drvdata(pdev, NULL); + kfree(ts); + + return 0; +} + +static struct platform_driver tsc_driver = { + .probe = tsc_probe, + .remove = __devexit_p(tsc_remove), + .driver.name = "tnetv107x-ts", + .driver.owner = THIS_MODULE, +}; + +static int __init tsc_init(void) +{ + return platform_driver_register(&tsc_driver); +} + +static void __exit tsc_exit(void) +{ + platform_driver_unregister(&tsc_driver); +} + +module_init(tsc_init); +module_exit(tsc_exit); + +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_DESCRIPTION("TNETV107X Touchscreen Driver"); +MODULE_ALIAS("platform: tnetv107x-ts"); +MODULE_LICENSE("GPL"); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:09 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:09 -0700 Subject: [PATCH 45/47] davinci: add tnetv107x touchscreen platform device In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-46-git-send-email-khilman@deeprootsystems.com> From: Cyril Chemparathy This patch adds a platform device definition for tnetv107x's touchscreen controller. Signed-off-by: Cyril Chemparathy Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/devices-tnetv107x.c | 20 ++++++++++++++++++++ 1 files changed, 20 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 086269f..c9a86d8 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -31,6 +31,7 @@ #define TNETV107X_TPTC0_BASE 0x01c10000 #define TNETV107X_TPTC1_BASE 0x01c10400 #define TNETV107X_WDOG_BASE 0x08086700 +#define TNETV107X_TSC_BASE 0x08088500 #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 @@ -323,12 +324,31 @@ static struct platform_device keypad_device = { .resource = keypad_resources, }; +static struct resource tsc_resources[] = { + { + .start = TNETV107X_TSC_BASE, + .end = TNETV107X_TSC_BASE + 0xff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_TSC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tsc_device = { + .name = "tnetv107x-ts", + .num_resources = ARRAY_SIZE(tsc_resources), + .resource = tsc_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; platform_device_register(&edma_device); platform_device_register(&tnetv107x_wdt_device); + platform_device_register(&tsc_device); if (info->serial_config) davinci_serial_init(info->serial_config); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:10 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:10 -0700 Subject: [PATCH 46/47] davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-47-git-send-email-khilman@deeprootsystems.com> From: Michael Williamson For the MityDSP-L138/MityARM-1808 SOMS, read the factory assigned MAC address from the onboard I2C EPROM and assign it to the emac device during platform initialization. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman --- arch/arm/mach-davinci/board-mityomapl138.c | 62 ++++++++++++++++++++++++++++ 1 files changed, 62 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 6f12a18..65f7501 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -25,6 +27,65 @@ #include #define MITYOMAPL138_PHY_ID "0:03" + +#define FACTORY_CONFIG_MAGIC 0x012C0138 +#define FACTORY_CONFIG_VERSION 0x00010001 + +/* Data Held in On-Board I2C device */ +struct factory_config { + u32 magic; + u32 version; + u8 mac[6]; + u32 fpga_type; + u32 spare; + u32 serialnumber; + char partnum[32]; +}; + +static struct factory_config factory_config; + +static void read_factory_config(struct memory_accessor *a, void *context) +{ + int ret; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + ret = a->read(a, (char *)&factory_config, 0, sizeof(factory_config)); + if (ret != sizeof(struct factory_config)) { + pr_warning("MityOMAPL138: Read Factory Config Failed: %d\n", + ret); + return; + } + + if (factory_config.magic != FACTORY_CONFIG_MAGIC) { + pr_warning("MityOMAPL138: Factory Config Magic Wrong (%X)\n", + factory_config.magic); + return; + } + + if (factory_config.version != FACTORY_CONFIG_VERSION) { + pr_warning("MityOMAPL138: Factory Config Version Wrong (%X)\n", + factory_config.version); + return; + } + + pr_info("MityOMAPL138: Found MAC = %pM\n", factory_config.mac); + pr_info("MityOMAPL138: Part Number = %s\n", factory_config.partnum); + if (is_valid_ether_addr(factory_config.mac)) + memcpy(soc_info->emac_pdata->mac_addr, + factory_config.mac, ETH_ALEN); + else + pr_warning("MityOMAPL138: Invalid MAC found " + "in factory config block\n"); +} + +static struct at24_platform_data mityomapl138_fd_chip = { + .byte_len = 256, + .page_size = 8, + .flags = AT24_FLAG_READONLY | AT24_FLAG_IRUGO, + .setup = read_factory_config, + .context = NULL, +}; + static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { .bus_freq = 100, /* kHz */ .bus_delay = 0, /* usec */ @@ -151,6 +212,7 @@ static struct i2c_board_info __initdata mityomap_tps65023_info[] = { }, { I2C_BOARD_INFO("24c02", 0x50), + .platform_data = &mityomapl138_fd_chip, }, }; -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 16:30:11 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 1 Oct 2010 14:30:11 -0700 Subject: [PATCH 47/47] davinci: Initial support for Omapl138-Hawkboard In-Reply-To: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> Message-ID: <1285968611-26890-48-git-send-email-khilman@deeprootsystems.com> From: Victor Rodriguez This patch adds initial support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Information on these system may be found at http://www.hawkboard.org. Basic support for the UART console is included in this patch. It's tested with latest Angstrom File Systems like ramdisk from http://alturl.com/imb45. Signed-off-by: Victor Rodriguez Signed-off-by: Kevin Hilman --- arch/arm/configs/da8xx_omapl_defconfig | 1 + arch/arm/mach-davinci/Kconfig | 8 +++ arch/arm/mach-davinci/Makefile | 1 + arch/arm/mach-davinci/board-omapl138-hawk.c | 64 +++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/uncompress.h | 1 + 5 files changed, 75 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/board-omapl138-hawk.c diff --git a/arch/arm/configs/da8xx_omapl_defconfig b/arch/arm/configs/da8xx_omapl_defconfig index f8a47ee..cdc40c4 100644 --- a/arch/arm/configs/da8xx_omapl_defconfig +++ b/arch/arm/configs/da8xx_omapl_defconfig @@ -18,6 +18,7 @@ CONFIG_ARCH_DAVINCI=y CONFIG_ARCH_DAVINCI_DA830=y CONFIG_ARCH_DAVINCI_DA850=y CONFIG_MACH_MITYOMAPL138=y +CONFIG_MACH_OMAPL138_HAWKBOARD=y CONFIG_DAVINCI_RESET_CLOCKS=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 9aca60c..b77b860 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -193,6 +193,14 @@ config MACH_MITYOMAPL138 System on Module. Information on this SoM may be found at http://www.mitydsp.com +config MACH_OMAPL138_HAWKBOARD + bool "TI AM1808 / OMAPL-138 Hawkboard platform" + depends on ARCH_DAVINCI_DA850 + help + Say Y here to select the TI AM1808 / OMAPL-138 Hawkboard platform . + Information of this board may be found at + http://www.hawkboard.org/ + config DAVINCI_MUX bool "DAVINCI multiplexing support" depends on ARCH_DAVINCI diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index a7a70d1..0b87a1c 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o +obj-$(CONFIG_MACH_OMAPL138_HAWKBOARD) += board-omapl138-hawk.o # Power Management obj-$(CONFIG_CPU_FREQ) += cpufreq.o diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c new file mode 100644 index 0000000..c472dd8 --- /dev/null +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -0,0 +1,64 @@ +/* + * Hawkboard.org based on TI's OMAP-L138 Platform + * + * Initial code: Syed Mohammed Khasim + * + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ +#include +#include +#include +#include + +#include +#include + +#include +#include + +static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { + .enabled_uarts = 0x7, +}; + +static __init void omapl138_hawk_init(void) +{ + int ret; + + davinci_serial_init(&omapl138_hawk_uart_config); + + ret = da8xx_register_watchdog(); + if (ret) + pr_warning("omapl138_hawk_init: " + "watchdog registration failed: %d\n", + ret); +} + +#ifdef CONFIG_SERIAL_8250_CONSOLE +static int __init omapl138_hawk_console_init(void) +{ + if (!machine_is_omapl138_hawkboard()) + return 0; + + return add_preferred_console("ttyS", 2, "115200"); +} +console_initcall(omapl138_hawk_console_init); +#endif + +static void __init omapl138_hawk_map_io(void) +{ + da850_init(); +} + +MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") + .phys_io = IO_PHYS, + .io_pg_offst = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc, + .boot_params = (DA8XX_DDR_BASE + 0x100), + .map_io = omapl138_hawk_map_io, + .init_irq = cp_intc_init, + .timer = &davinci_timer, + .init_machine = omapl138_hawk_init, +MACHINE_END diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index d370391..47723e8 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -89,6 +89,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_DA8XX(davinci_da830_evm, 2); DEBUG_LL_DA8XX(davinci_da850_evm, 2); DEBUG_LL_DA8XX(mityomapl138, 1); + DEBUG_LL_DA8XX(omapl138_hawkboard, 2); /* TNETV107x boards */ DEBUG_LL_TNETV107X(tnetv107x, 1); -- 1.7.2.1 From khilman at deeprootsystems.com Fri Oct 1 17:05:16 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 01 Oct 2010 15:05:16 -0700 Subject: [PATCH v5 1/4] davinci: Add generic PWM support for PWM control In-Reply-To: <1284968386-16898-1-git-send-email-sugumar@ti.com> (Sugumar Natarajan's message of "Mon, 20 Sep 2010 13:09:46 +0530") References: <1284968386-16898-1-git-send-email-sugumar@ti.com> Message-ID: <8739sp7en7.fsf@deeprootsystems.com> Sugumar Natarajan writes: > This patch adds generic PWM support where it maintains the > list of PWM control devices that can be added or removed. > > The interface provides a list of functions that can be accessed > by the PWM control driver module and the generic PWM driver. > > The PWM control driver module such as eCAP uses the interface to > register and add itself to the list as a PWM control device. > The generic PWM driver uses the interface to search for a PWM control > device and if present, uses the device for PWM control. > > Signed-off-by: Sugumar Natarajan Sugumar, Would you mind having a look at a generic PWM layer that was recently proposed. Being familiar with the PWM needs on davinci, your feedback would be very valuable on this series. http://marc.info/?l=linux-embedded&r=1&b=201010&w=2 If we can adapt davinci usage to a more generic framework, that would be even better. Thanks, Kevin > --- > Changes since v4: > a) pwm_enable and pwm_disable function implementation have been modified, > such that the actual implementation is done by the corresponding driver, > and these functions would just make a callback. > > arch/arm/mach-davinci/Makefile | 3 + > arch/arm/mach-davinci/davinci_pwm.c | 135 ++++++++++++++++++++++ > arch/arm/mach-davinci/include/mach/davinci_pwm.h | 34 ++++++ > 3 files changed, 172 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-davinci/davinci_pwm.c > create mode 100644 arch/arm/mach-davinci/include/mach/davinci_pwm.h > > diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile > index a7a70d1..90ca821 100644 > --- a/arch/arm/mach-davinci/Makefile > +++ b/arch/arm/mach-davinci/Makefile > @@ -39,3 +39,6 @@ obj-$(CONFIG_MACH_MITYOMAPL138) += board-mityomapl138.o > obj-$(CONFIG_CPU_FREQ) += cpufreq.o > obj-$(CONFIG_CPU_IDLE) += cpuidle.o > obj-$(CONFIG_SUSPEND) += pm.o sleep.o > + > +# Generic PWM control support > +obj-$(CONFIG_HAVE_PWM) += davinci_pwm.o > diff --git a/arch/arm/mach-davinci/davinci_pwm.c b/arch/arm/mach-davinci/davinci_pwm.c > new file mode 100644 > index 0000000..8f3e8ad > --- /dev/null > +++ b/arch/arm/mach-davinci/davinci_pwm.c > @@ -0,0 +1,135 @@ > +/* > + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed .as is. WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) > +{ > + unsigned int clock_freq; > + unsigned int period_cycles; > + unsigned int duty_cycle; > + int ret = 0; > + > + if (WARN_ON(!pwm)) > + return -EINVAL; > + > + if (pwm->pwm_config_device) { > + if (!period_ns || duty_ns > period_ns) > + return -EINVAL; > + > + clock_freq = clk_get_rate(pwm->clk) / USEC_PER_SEC; > + period_cycles = (clock_freq * period_ns) / MSEC_PER_SEC; > + duty_cycle = (clock_freq * duty_ns) / MSEC_PER_SEC; > + > + ret = pwm->pwm_config_device(pwm, period_cycles, duty_cycle); > + } > + > + return ret; > +} > +EXPORT_SYMBOL(pwm_config); > + > +int pwm_enable(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return -EINVAL; > + > + if (pwm->pwm_enable) > + return pwm->pwm_enable(pwm); > + > + return 0; > +} > +EXPORT_SYMBOL(pwm_enable); > + > +void pwm_disable(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + if (pwm->pwm_disable) > + pwm->pwm_disable(pwm); > +} > +EXPORT_SYMBOL(pwm_disable); > + > +static DEFINE_MUTEX(pwm_lock); > +static LIST_HEAD(pwm_list); > + > +struct pwm_device *pwm_request(int pwm_id, const char *label) > +{ > + struct pwm_device *pwm, *tmp_pwm = ERR_PTR(-ENOENT); > + > + mutex_lock(&pwm_lock); > + > + list_for_each_entry(pwm, &pwm_list, node) { > + if (pwm->pwm_id == pwm_id) { > + if (pwm->use_count == 0) { > + pwm->use_count++; > + pwm->label = label; > + } else { > + pwm = ERR_PTR(-EBUSY); > + } > + tmp_pwm = pwm; > + break; > + } > + } > + > + mutex_unlock(&pwm_lock); > + return tmp_pwm; > +} > +EXPORT_SYMBOL(pwm_request); > + > +void pwm_free(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + > + if (pwm->use_count) { > + pwm->use_count--; > + pwm->label = NULL; > + } else { > + dev_warn(&pwm->pdev->dev, "PWM device already freed\n"); > + } > + > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_free); > + > +void pwm_add(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + list_add_tail(&pwm->node, &pwm_list); > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_add); > + > +void pwm_remove(struct pwm_device *pwm) > +{ > + if (WARN_ON(!pwm)) > + return; > + > + mutex_lock(&pwm_lock); > + list_del(&pwm->node); > + mutex_unlock(&pwm_lock); > +} > +EXPORT_SYMBOL(pwm_remove); > diff --git a/arch/arm/mach-davinci/include/mach/davinci_pwm.h b/arch/arm/mach-davinci/include/mach/davinci_pwm.h > new file mode 100644 > index 0000000..5762881 > --- /dev/null > +++ b/arch/arm/mach-davinci/include/mach/davinci_pwm.h > @@ -0,0 +1,34 @@ > +/* > + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed .as is. WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + */ > + > +#ifndef __DAVINCI_PWM_H > +#define __DAVINCI_PWM_H > + > +struct pwm_device { > + struct list_head node; > + struct platform_device *pdev; > + int (*pwm_enable)(struct pwm_device *pwm); > + void (*pwm_disable)(struct pwm_device *pwm); > + int (*pwm_config_device)(struct pwm_device *pwm, > + unsigned int period, unsigned int dutycycle); > + const char *label; > + struct clk *clk; > + unsigned int use_count; > + unsigned int pwm_id; > +}; > + > +void pwm_add(struct pwm_device *pwm); > +void pwm_remove(struct pwm_device *pwm); > + > +#endif From caglarakyuz at gmail.com Sat Oct 2 10:00:52 2010 From: caglarakyuz at gmail.com (Caglar Akyuz) Date: Sat, 2 Oct 2010 18:00:52 +0300 Subject: [PATCH v7] davinci: Initial support for Omapl138-Hawkboard In-Reply-To: <87lj6rkxu2.fsf@deeprootsystems.com> References: <1285259320-2541-1-git-send-email-vm.rod25@gmail.com> <87lj6rkxu2.fsf@deeprootsystems.com> Message-ID: <201010021800.52224.caglarakyuz@gmail.com> On Friday 24 September 2010 05:41:57 pm Kevin Hilman wrote: > Victor Rodriguez writes: > > This patch adds initial support for the Hawkboard-L138 system > > It is under the machine name "omapl138_hawkboard". > > This system is based on the da850 davinci CPU architecture. > > Information on these system may be found at http://www.hawkboard.org. > > Basic support for the UART console is included in this patch. > > It's tested with latest Angstrom File Systems like ramdisk > > from http://alturl.com/imb45. > > > > Signed-off-by: Victor Rodriguez > > --- > > Changes since v6: > > 1) Change commit reference > > 2) Remove hack that shut down UART1 because > > it is unused at present on the hawkboard. > > Thanks for removing this. > > Applying and queuing for 2.6.37 in davinci-next. > > Kevin > This commit is missing as of today. I can't see this in your tree, commit is present but changes are not there. master branch has nothing related to Hawk. All changes are dissappearing after following commit: commit 3b910ca5eef70179ee4b2c9f195df6da4f402532 Author: Michael Williamson Date: Fri Sep 17 09:56:06 2010 -0400 davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom For the MityDSP-L138/MityARM-1808 SOMS, read the factory assigned MAC address from the onboard I2C EPROM and assign it to the emac device during platform initialization. Signed-off-by: Michael Williamson Signed-off-by: Kevin Hilman arch/arm/mach-davinci/board-mityomapl138.c | 62 1 files changed, 62 insertions(+), 0 deletions(-) Am I missing something? Thanks, Caglar From vm.rod25 at gmail.com Sat Oct 2 10:10:06 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Sat, 2 Oct 2010 10:10:06 -0500 Subject: [PATCH v7] davinci: Initial support for Omapl138-Hawkboard In-Reply-To: <201010021800.52224.caglarakyuz@gmail.com> References: <1285259320-2541-1-git-send-email-vm.rod25@gmail.com> <87lj6rkxu2.fsf@deeprootsystems.com> <201010021800.52224.caglarakyuz@gmail.com> Message-ID: On Sat, Oct 2, 2010 at 10:00 AM, Caglar Akyuz wrote: > On Friday 24 September 2010 05:41:57 pm Kevin Hilman wrote: >> Victor Rodriguez writes: >> > This patch adds initial support for the Hawkboard-L138 system >> > It is under the machine name "omapl138_hawkboard". >> > This system is based on the da850 davinci CPU architecture. >> > Information on these system may be found at http://www.hawkboard.org. >> > Basic support for the UART console is included in this patch. >> > It's tested with latest Angstrom File Systems like ramdisk >> > from http://alturl.com/imb45. >> > >> > Signed-off-by: Victor Rodriguez >> > --- >> > Changes since v6: >> > 1) Change commit reference >> > 2) Remove hack that shut down UART1 because >> > it is unused at present on the hawkboard. >> >> Thanks for removing this. >> >> Applying and queuing for 2.6.37 in davinci-next. >> >> Kevin >> > > This commit is missing as of today. I can't see this in your tree, commit is > present but changes are not there. master branch has nothing related to Hawk. > > All changes are dissappearing after following commit: > > ? ? ? commit 3b910ca5eef70179ee4b2c9f195df6da4f402532 > ? ? ? Author: Michael Williamson > ? ? ? Date: ? Fri Sep 17 09:56:06 2010 -0400 > > ? ? ? davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom > > ? ? ? For the MityDSP-L138/MityARM-1808 SOMS, read the factory assigned > ? ? ? MAC address from the onboard I2C EPROM and assign it to the emac > ? ? ? device during platform initialization. > > ? ? ? Signed-off-by: Michael Williamson > ? ? ? Signed-off-by: Kevin Hilman > > ? ? ?arch/arm/mach-davinci/board-mityomapl138.c | ? 62 > ? ? ?1 files changed, 62 insertions(+), 0 deletions(-) > > Am I missing something? > > Thanks, > Caglar > Hi Caglar I am out of office but did you said that git pull apply all the changes that Kevin send yesterd to mailing list except for hawkboard? From paheliprasad at gmail.com Sun Oct 3 00:16:22 2010 From: paheliprasad at gmail.com (kunal singh) Date: Sun, 3 Oct 2010 10:46:22 +0530 Subject: problem with serial console In-Reply-To: References: <2A3DCF3DA181AD40BDE86A3150B27B6B0356476D44@dbde02.ent.ti.com> Message-ID: While doing the early console set up, there is a function call to drivers/serial/8250_early.c/serial8250_find_port_For_earlycon() The above function always returns with an error condition. It does checks on the early_device and these checks fail (it fails because the early_device.port is un-initialized). I checked the code and see that early_device (which is a static variable) is never intialzed any where in the code drivers/serial/8250_early.c. I wonder if the earlycon support has been added for 2.6.32 kernel? any suggestions? On Thu, Sep 30, 2010 at 9:18 PM, kunal singh wrote: > Tried with earlyprintk, but the problem persists > > > On Thu, Sep 30, 2010 at 8:45 PM, kunal singh wrote: > >> Hi Hemant, >> >> No I have not added the earlyprintk. I will investigate this. Shall I >> add earlyprintk=serial,uart0 ? >> >> BTW, I tried to trace down the printk code flow in kernel/printk.c. >> (1) in the function _call_console_drivers(), __call_console_drivers() >> never gets called [the if() condition is never met]. >> (2) May be it probably explains why nothing gets printed on serial? Is >> this because there is no earlyprintk in bootargs? >> >> Regards, >> kunal >> >> >> >> >> >> On Thu, Sep 30, 2010 at 8:19 PM, Pedanekar, Hemant wrote: >> >>> Just to check: have you added "earlyprintk" to your bootargs? >>> >>> - >>> Hemant >>> >>> >>> >>> ------------------------------ >>> *From:* kunal singh [mailto:paheliprasad at gmail.com] >>> *Sent:* Thursday, September 30, 2010 7:40 PM >>> *To:* Raffaele Recalcati; Nori, Sekhar; Pedanekar, Hemant >>> >>> *Cc:* davinci-linux-open-source at linux.davincidsp.com >>> *Subject:* Re: problem with serial console >>> >>> Hi All, >>> >>> >>> Thanks a lot for posting the comments here. >>> >>> (1) I have added some printascii() statements in function >>> init/main.c/start_kernel() to trace the boot sequence >>> (a) printascii() to print the command line arguments >>> (b) printascii() before doing the console_init() >>> (c) printascii() after doing the console_init() >>> >>> (2) The log (posted below) suggests that the boot sequence goes beyond >>> console_init(). Since console_init is done I would expect that all my printk >>> messages should start to appear on the console . But it does not. (however >>> the printascii still works, as you can see messages in the bootlog, hence I >>> would assume that hardware is fine) >>> >>> I would appreciate if you can give some suggestion on how to debug >>> this issue further. >>> >>> Thanks, >>> kunal >>> >>> >>> /************* HERE IS THE BOOT LOG ****************************/ >>> run devboot >>> TFTP from server 10.0.0.1; our IP address is 10.0.0.3 >>> Filename '/home/kunal/xcaster/ingenient-bsp/images/uImage'. >>> Load address: 0x82000000 >>> Loading: #T >>> ################################################################ >>> >>> ################################################################# >>> #################T >>> ################################################ >>> >>> ################################################################## >>> ###################T ##########T >>> #################################### >>> ##########################################T #### >>> done >>> Bytes transferred = 1898780 (1cf91c hex) >>> ## Booting image at 82000000 ... >>> Image Name: Linux-2.6.32-rc2-davinci1 >>> Image Type: ARM Linux Kernel Image (uncompressed) >>> Data Size: 1898716 Bytes = 1.8 MB >>> Load Address: 80008000 >>> Entry Point: 80008000 >>> Verifying Checksum ... OK >>> OK >>> >>> Starting kernel ... >>> >>> Uncompressing >>> Linux........................................................................................................................... >>> done, booting the kernel. >>> >>> console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=10.0.0.1:/home/kunal/xcaster/ingenient-bsp/rootfs/fs,udp,v3,rsize=4096,wsize=1400 >>> ip=10.0.0.3:10.0.0.1:10.0.0.1:255.255.255.0:XCASTER5000::off mem=128M >>> mtdparts=davinci-nand.0:96k(ubl),736k(uboot),64k(uboot-env),2m(kernel),61568k(app) >>> eth=80:4C:EF:54:87:0A >>> doing console init now >>> finished console init >>> >>> /***************************************************************/ >>> >>> >>> On Thu, Sep 30, 2010 at 6:26 PM, Raffaele Recalcati < >>> lamiaposta71 at gmail.com> wrote: >>> >>>> On Thu, Sep 30, 2010 at 2:35 PM, kunal singh >>>> wrote: >>>> > Hi Raffaele, >>>> > >>>> > Thanks for the suggestion. >>>> > >>>> > (1) Console is fine. I am able to communicate with the u-boot >>>> (115200,n8). >>>> > Also if I use printascii (a kernel function) I am able to output on >>>> console. >>>> > (2) There is no message, after the kernel decompression (because >>>> console is >>>> > not up). Here is what I see. >>>> > >>>> > Load address: 0x82000000 >>>> > Loading: ####T ###################T >>>> > ########################################## >>>> > >>>> ################################################################## >>>> > ######################T >>>> > ############################################ >>>> > >>>> ################################################################# >>>> > ###################T >>>> > ##############################################T ## >>>> > ######T ######################################## >>>> > done >>>> > Bytes transferred = 1898828 (1cf94c hex) >>>> > ## Booting image at 82000000 ... >>>> > Image Name: Linux-2.6.32-rc2-davinci1 >>>> > Image Type: ARM Linux Kernel Image (uncompressed) >>>> > Data Size: 1898764 Bytes = 1.8 MB >>>> > Load Address: 80008000 >>>> > Entry Point: 80008000 >>>> > Verifying Checksum ... OK >>>> > OK >>>> > >>>> > Starting kernel ... >>>> > >>>> > Uncompressing >>>> > >>>> Linux........................................................................................................................... >>>> > done, booting the kernel. >>>> > >>>> > /* AND THEN NOTHING BECAUSE CONSOLE IS NOT FUNCTIONAL, but booting >>>> goes on >>>> > */ >>>> >>>> How can you say that boot goes on? >>>> Can you check mem inside bootargs? >>>> For instance I have 128MB RAM and I use these bootargs. >>>> >>>> set bootargs 'console=ttyS0,115200n8 rw >>>> ip=10.39.10.183:10.39.10.169:10.39.8.1:255.255.248.0:::off >>>> root=/dev/nfs nfsroot=10.39.10.169:/home/NFS/ARAGO_DEMO_IMAGE-raf/ >>>> mem=128M video=davincifb:output=lcd:format=rgb:vid0=240x320 at 0 >>>> ,0:vid1=240x320 at 0,0:osd0=240x320 at 0,0:osd1=240x320 at 0,0 >>>> ' >>>> >>>> Don't copy my bootargs, only do some tests. >>>> I saw your behaviour when mem was wrong. >>>> >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chtpatil at gmail.com Sun Oct 3 03:55:12 2010 From: chtpatil at gmail.com (chetan patil) Date: Sun, 3 Oct 2010 14:25:12 +0530 Subject: Compiling Sample code in SDK. Message-ID: I tried to compile sample code which came when i installed the SDK. I got following error. .h files are installed then also it says file not found. ----------------------------------------------------------------------------------------------------------------------------------------- [root at chetanpatil encode]# gcc main.c -o first main.c:22:21: error: xdc/std.h: No such file or directory main.c:24:32: error: ti/sdo/ce/trace/gt.h: No such file or directory main.c:25:33: error: ti/sdo/ce/CERuntime.h: No such file or directory main.c:26:45: error: ti/sdo/ce/utils/trace/TraceUtil.h: No such file or directory main.c:28:30: error: ti/sdo/dmai/Dmai.h: No such file or directory main.c:29:30: error: ti/sdo/dmai/Fifo.h: No such file or directory main.c:30:31: error: ti/sdo/dmai/Pause.h: No such file or directory main.c:31:31: error: ti/sdo/dmai/Sound.h: No such file or directory main.c:32:34: error: ti/sdo/dmai/VideoStd.h: No such file or directory main.c:33:33: error: ti/sdo/dmai/Display.h: No such file or directory main.c:34:33: error: ti/sdo/dmai/Capture.h: No such file or directory main.c:35:35: error: ti/sdo/dmai/BufferGfx.h: No such file or directory main.c:36:36: error: ti/sdo/dmai/Rendezvous.h: No such file or directory In file included from main.c:38: video.h:23: error: expected specifier-qualifier-list before ?Rendezvous_Handle? video.h:42: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?*? token In file included from main.c:39: capture.h:25: error: expected specifier-qualifier-list before ?Rendezvous_Handle? capture.h:41: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?*? token In file included from main.c:40: writer.h:23: error: expected specifier-qualifier-list before ?Rendezvous_Handle? writer.h:33: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?*? token In file included from main.c:41: speech.h:23: error: expected specifier-qualifier-list before ?Rendezvous_Handle? speech.h:35: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?*? token In file included from ../ctrl.h:20, from main.c:42: ../ui.h:17:32: error: ti/sdo/dmai/Buffer.h: No such file or directory In file included from ../ui.h:20, from ../ctrl.h:20, from main.c:42: ../uibuttons.h:19:38: error: ti/sdo/simplewidget/Font.h: No such file or directory In file included from ../ui.h:20, from ../ctrl.h:20, from main.c:42: ../uibuttons.h:49: error: expected specifier-qualifier-list before ?Int32? ../uibuttons.h:60: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UIButtons_createButtons? ../uibuttons.h:62: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UIButtons_deleteButtons? ../uibuttons.h:64: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UIButtons_drawButtons? ../uibuttons.h:66: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UIButtons_pressButton? In file included from ../ctrl.h:20, from main.c:42: ../ui.h:55: error: expected specifier-qualifier-list before ?Int? ../ui.h:67: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_init? ../ui.h:69: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_pressButton? ../ui.h:71: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_updateValue? ../ui.h:73: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_setRow? ../ui.h:75: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_show? ../ui.h:77: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_hide? ../ui.h:79: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_toggleVisibility? ../ui.h:81: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_decTransparency? ../ui.h:83: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_incTransparency? ../ui.h:85: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_eraseData? ../ui.h:87: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_update? ../ui.h:89: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?UI_delete? In file included from main.c:42: ../ctrl.h:28: error: expected specifier-qualifier-list before ?Rendezvous_Handle? ../ctrl.h:37: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?*? token In file included from main.c:43: ../demo.h:32: error: expected specifier-qualifier-list before ?Char? ../demo.h:49: error: expected specifier-qualifier-list before ?Char? ../demo.h:75: error: expected specifier-qualifier-list before ?Int? ../demo.h:91: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetQuit? ../demo.h:102: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblSetQuit? ../demo.h:109: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetAndResetFrames? ../demo.h:121: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblIncFrames? ../demo.h:128: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetAndResetVideoBytesProcessed? ../demo.h:140: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblIncVideoBytesProcessed? ../demo.h:147: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetAndResetSoundBytesProcessed? ../demo.h:159: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblIncSoundBytesProcessed? ../demo.h:166: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetSamplingFrequency? ../demo.h:177: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblSetSamplingFrequency? ../demo.h:184: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetImageWidth? ../demo.h:195: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblSetImageWidth? ../demo.h:202: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblGetImageHeight? ../demo.h:213: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?gblSetImageHeight? main.c:61: error: expected specifier-qualifier-list before ?Display_Output? main.c:86: warning: excess elements in struct initializer main.c:86: warning: (near initialization for ?gbl?) main.c:91: error: expected ?)? before ?*? token main.c:151: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?parseArgs? main.c: In function ?uiSetup?: main.c:329: error: ?UI_Attrs? has no member named ?osd? main.c:329: error: ?Args? has no member named ?osd? main.c:330: error: ?UI_Attrs? has no member named ?videoStd? main.c:330: error: ?Args? has no member named ?videoStd? main.c:341: error: ?Args? has no member named ?videoStdString? main.c:343: error: ?Args? has no member named ?videoEncoder? main.c:344: error: ?Args? has no member named ?videoEncoder? main.c:350: error: ?Args? has no member named ?speechEncoder? main.c:351: error: ?Args? has no member named ?speechEncoder? main.c: At top level: main.c:369: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? before ?main? --------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From martin at ti.com Sun Oct 3 16:44:19 2010 From: martin at ti.com (martin at ti.com) Date: Sun, 3 Oct 2010 16:44:19 -0500 Subject: [PATCH 1/1] ALSA: ASoc: DaVinci Delay start of ASP to trigger Message-ID: <1286142259-6625-1-git-send-email-martin@ti.com> From: Troy Kisky Since only 4 mainline ASoC codecs support the trigger callback, we cannot rely upon them stopping the frame clock if they are master and must assume it is running even if the sound is paused. Thus we cannot start the ASP until the trigger method. Signed-off-by: Troy Kisky Signed-off-by: Martin Ambrose --- sound/soc/davinci/davinci-i2s.c | 6 ------ 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 9e8932a..a66c237 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -572,10 +572,6 @@ static int davinci_i2s_prepare(struct snd_pcm_substream *substream, struct davinci_mcbsp_dev *dev = dai->private_data; int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); davinci_mcbsp_stop(dev, playback); - if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) { - /* codec is master */ - davinci_mcbsp_start(dev, substream); - } return 0; } @@ -585,8 +581,6 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct davinci_mcbsp_dev *dev = dai->private_data; int ret = 0; int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); - if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) - return 0; /* return if codec is master */ switch (cmd) { case SNDRV_PCM_TRIGGER_START: -- 1.7.0.4 From spoulsen at css-design.com Sun Oct 3 21:33:24 2010 From: spoulsen at css-design.com (Steve Poulsen) Date: Sun, 03 Oct 2010 21:33:24 -0500 Subject: Compiling Sample code in SDK. In-Reply-To: References: Message-ID: <4CA93CF4.30703@css-design.com> Is there a Makefile in the folder? Try using "make" instead. Also, make sure the paths in Rules.mak at DVSDK root are correct. On 10/3/2010 3:55 AM, chetan patil wrote: > I tried to compile sample code which came when i installed the SDK. > I got following error. > .h files are installed then also it says file not found. > > ----------------------------------------------------------------------------------------------------------------------------------------- > > [root at chetanpatil encode]# gcc main.c -o first > main.c:22:21: error: xdc/std.h: No such file or directory > main.c:24:32: error: ti/sdo/ce/trace/gt.h: No such file or directory > main.c:25:33: error: ti/sdo/ce/CERuntime.h: No such file or directory > main.c:26:45: error: ti/sdo/ce/utils/trace/TraceUtil.h: No such file > or directory > main.c:28:30: error: ti/sdo/dmai/Dmai.h: No such file or directory > main.c:29:30: error: ti/sdo/dmai/Fifo.h: No such file or directory > main.c:30:31: error: ti/sdo/dmai/Pause.h: No such file or directory > main.c:31:31: error: ti/sdo/dmai/Sound.h: No such file or directory > main.c:32:34: error: ti/sdo/dmai/VideoStd.h: No such file or directory > main.c:33:33: error: ti/sdo/dmai/Display.h: No such file or directory > main.c:34:33: error: ti/sdo/dmai/Capture.h: No such file or directory > main.c:35:35: error: ti/sdo/dmai/BufferGfx.h: No such file or directory > main.c:36:36: error: ti/sdo/dmai/Rendezvous.h: No such file or directory > In file included from main.c:38: > video.h:23: error: expected specifier-qualifier-list before > ?Rendezvous_Handle? > video.h:42: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?*? token > In file included from main.c:39: > capture.h:25: error: expected specifier-qualifier-list before > ?Rendezvous_Handle? > capture.h:41: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?*? token > In file included from main.c:40: > writer.h:23: error: expected specifier-qualifier-list before > ?Rendezvous_Handle? > writer.h:33: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?*? token > In file included from main.c:41: > speech.h:23: error: expected specifier-qualifier-list before > ?Rendezvous_Handle? > speech.h:35: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?*? token > In file included from ../ctrl.h:20, > from main.c:42: > ../ui.h:17:32: error: ti/sdo/dmai/Buffer.h: No such file or directory > In file included from ../ui.h:20, > from ../ctrl.h:20, > from main.c:42: > ../uibuttons.h:19:38: error: ti/sdo/simplewidget/Font.h: No such file > or directory > In file included from ../ui.h:20, > from ../ctrl.h:20, > from main.c:42: > ../uibuttons.h:49: error: expected specifier-qualifier-list before ?Int32? > ../uibuttons.h:60: error: expected ?=?, ?,?, ?;?, ?asm? or > ?__attribute__? before ?UIButtons_createButtons? > ../uibuttons.h:62: error: expected ?=?, ?,?, ?;?, ?asm? or > ?__attribute__? before ?UIButtons_deleteButtons? > ../uibuttons.h:64: error: expected ?=?, ?,?, ?;?, ?asm? or > ?__attribute__? before ?UIButtons_drawButtons? > ../uibuttons.h:66: error: expected ?=?, ?,?, ?;?, ?asm? or > ?__attribute__? before ?UIButtons_pressButton? > In file included from ../ctrl.h:20, > from main.c:42: > ../ui.h:55: error: expected specifier-qualifier-list before ?Int? > ../ui.h:67: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_init? > ../ui.h:69: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_pressButton? > ../ui.h:71: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_updateValue? > ../ui.h:73: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_setRow? > ../ui.h:75: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_show? > ../ui.h:77: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_hide? > ../ui.h:79: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_toggleVisibility? > ../ui.h:81: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_decTransparency? > ../ui.h:83: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_incTransparency? > ../ui.h:85: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_eraseData? > ../ui.h:87: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_update? > ../ui.h:89: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?UI_delete? > In file included from main.c:42: > ../ctrl.h:28: error: expected specifier-qualifier-list before > ?Rendezvous_Handle? > ../ctrl.h:37: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?*? token > In file included from main.c:43: > ../demo.h:32: error: expected specifier-qualifier-list before ?Char? > ../demo.h:49: error: expected specifier-qualifier-list before ?Char? > ../demo.h:75: error: expected specifier-qualifier-list before ?Int? > ../demo.h:91: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetQuit? > ../demo.h:102: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblSetQuit? > ../demo.h:109: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetAndResetFrames? > ../demo.h:121: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblIncFrames? > ../demo.h:128: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetAndResetVideoBytesProcessed? > ../demo.h:140: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblIncVideoBytesProcessed? > ../demo.h:147: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetAndResetSoundBytesProcessed? > ../demo.h:159: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblIncSoundBytesProcessed? > ../demo.h:166: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetSamplingFrequency? > ../demo.h:177: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblSetSamplingFrequency? > ../demo.h:184: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetImageWidth? > ../demo.h:195: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblSetImageWidth? > ../demo.h:202: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblGetImageHeight? > ../demo.h:213: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?gblSetImageHeight? > main.c:61: error: expected specifier-qualifier-list before > ?Display_Output? > main.c:86: warning: excess elements in struct initializer > main.c:86: warning: (near initialization for ?gbl?) > main.c:91: error: expected ?)? before ?*? token > main.c:151: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?parseArgs? > main.c: In function ?uiSetup?: > main.c:329: error: ?UI_Attrs? has no member named ?osd? > main.c:329: error: ?Args? has no member named ?osd? > main.c:330: error: ?UI_Attrs? has no member named ?videoStd? > main.c:330: error: ?Args? has no member named ?videoStd? > main.c:341: error: ?Args? has no member named ?videoStdString? > main.c:343: error: ?Args? has no member named ?videoEncoder? > main.c:344: error: ?Args? has no member named ?videoEncoder? > main.c:350: error: ?Args? has no member named ?speechEncoder? > main.c:351: error: ?Args? has no member named ?speechEncoder? > main.c: At top level: > main.c:369: error: expected ?=?, ?,?, ?;?, ?asm? or ?__attribute__? > before ?main? > > --------------------------------------------------------------------------------------------------------------------------------------------------------------------- > > -- > Regards, > > Chetan Arvind Patil, > +919970018364 > http://sites.google.com/site/chtpatil/ > > > -- > This message has been scanned for viruses and > dangerous content by *MailScanner* , and is > believed to be clean. > > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. -------------- next part -------------- An HTML attachment was scrubbed... URL: From deepali at ti.com Mon Oct 4 01:56:47 2010 From: deepali at ti.com (Uppal, Deepali) Date: Mon, 4 Oct 2010 12:26:47 +0530 Subject: Trying to move from 1.3x dsplink to 1.65 (does ips.h replace shm_ips.h) In-Reply-To: References: Message-ID: <2A3DCF3DA181AD40BDE86A3150B27B6B0356594339@dbde02.ent.ti.com> Brian, There are several changes from DSPLink 1.3x to 1.6x. Can you refer to the links at http://processors.wiki.ti.com/index.php/Category:DSPLink Specifically http://processors.wiki.ti.com/index.php/Migrating_between_DSPLink_versions In your email you have said that you have already looked at above links. You can edit the wiki pages to add the gaps that you have seen. At a top level, it can be said that ips.h replaces shm_ips.h. However, ips.h is an internal header file for the Notify module (notify.h)which does user level event notification. In the newer versions of DSPLink internal header files are not needed for an application level build. SO I think removing the header file altogether while moving to the latest DSPLink will work for you. Deepali -----Original Message----- From: davinci-linux-open-source-bounces+deepali=ti.com at linux.davincidsp.com [mailto:davinci-linux-open-source-bounces+deepali=ti.com at linux.davincidsp.com] On Behalf Of Brian Hutchinson Sent: Wednesday, September 29, 2010 7:59 PM To: davinci-linux-open-source at linux.davincidsp.com Subject: Trying to move from 1.3x dsplink to 1.65 (does ips.h replace shm_ips.h) I'm trying to make the changes to our dsp application to link against the latest community dsplink 1.65. The application is currently linked against a 1.30.08.02 version of dsplink that has a header file called shm_ips.h. This header doesn't show up in 1.65. Doing some grepping I see that 1.65 has: ips.h dsplinkips.h ldrv_ips.h ... I'm guessing that ips.h in 1.65 replaces shm_ips.h in 1.30? I've looked through the moving from 1.30 - 1.40 and 1.40 - 1.50 migration guides as well as release notes and I have yet to find anything addressing or documenting these changes. Has anyone experienced anything similar moving an old app (circa 2006) to the lastest dsplink? Regards, Brian _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source at linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From paheliprasad at gmail.com Mon Oct 4 04:57:57 2010 From: paheliprasad at gmail.com (kunal singh) Date: Mon, 4 Oct 2010 15:27:57 +0530 Subject: problem with serial console In-Reply-To: References: <2A3DCF3DA181AD40BDE86A3150B27B6B0356476D44@dbde02.ent.ti.com> Message-ID: Hi all, I have not been able to fix the issue with early printk. I still believe that it is not supported in the 2.6.32 open source kernel for davinci. However, I was able to fix problem with the kernel (by trial and error) and kernel boot is ok now. Thanks every one for your help on this issue. Regards, Kunal On Sun, Oct 3, 2010 at 10:46 AM, kunal singh wrote: > While doing the early console set up, there is a function call to > drivers/serial/8250_early.c/serial8250_find_port_For_earlycon() > > The above function always returns with an error condition. It does checks > on the early_device and these checks fail (it fails because the > early_device.port is un-initialized). > > I checked the code and see that early_device (which is a static variable) > is never intialzed any where in the code drivers/serial/8250_early.c. I > wonder if the earlycon support has been added for 2.6.32 kernel? any > suggestions? > > > On Thu, Sep 30, 2010 at 9:18 PM, kunal singh wrote: > >> Tried with earlyprintk, but the problem persists >> >> >> On Thu, Sep 30, 2010 at 8:45 PM, kunal singh wrote: >> >>> Hi Hemant, >>> >>> No I have not added the earlyprintk. I will investigate this. Shall I >>> add earlyprintk=serial,uart0 ? >>> >>> BTW, I tried to trace down the printk code flow in kernel/printk.c. >>> (1) in the function _call_console_drivers(), __call_console_drivers() >>> never gets called [the if() condition is never met]. >>> (2) May be it probably explains why nothing gets printed on serial? Is >>> this because there is no earlyprintk in bootargs? >>> >>> Regards, >>> kunal >>> >>> >>> >>> >>> >>> On Thu, Sep 30, 2010 at 8:19 PM, Pedanekar, Hemant wrote: >>> >>>> Just to check: have you added "earlyprintk" to your bootargs? >>>> >>>> - >>>> Hemant >>>> >>>> >>>> >>>> ------------------------------ >>>> *From:* kunal singh [mailto:paheliprasad at gmail.com] >>>> *Sent:* Thursday, September 30, 2010 7:40 PM >>>> *To:* Raffaele Recalcati; Nori, Sekhar; Pedanekar, Hemant >>>> >>>> *Cc:* davinci-linux-open-source at linux.davincidsp.com >>>> *Subject:* Re: problem with serial console >>>> >>>> Hi All, >>>> >>>> >>>> Thanks a lot for posting the comments here. >>>> >>>> (1) I have added some printascii() statements in function >>>> init/main.c/start_kernel() to trace the boot sequence >>>> (a) printascii() to print the command line arguments >>>> (b) printascii() before doing the console_init() >>>> (c) printascii() after doing the console_init() >>>> >>>> (2) The log (posted below) suggests that the boot sequence goes beyond >>>> console_init(). Since console_init is done I would expect that all my printk >>>> messages should start to appear on the console . But it does not. (however >>>> the printascii still works, as you can see messages in the bootlog, hence I >>>> would assume that hardware is fine) >>>> >>>> I would appreciate if you can give some suggestion on how to debug >>>> this issue further. >>>> >>>> Thanks, >>>> kunal >>>> >>>> >>>> /************* HERE IS THE BOOT LOG ****************************/ >>>> run devboot >>>> TFTP from server 10.0.0.1; our IP address is 10.0.0.3 >>>> Filename '/home/kunal/xcaster/ingenient-bsp/images/uImage'. >>>> Load address: 0x82000000 >>>> Loading: #T >>>> ################################################################ >>>> >>>> ################################################################# >>>> #################T >>>> ################################################ >>>> >>>> ################################################################## >>>> ###################T ##########T >>>> #################################### >>>> ##########################################T #### >>>> done >>>> Bytes transferred = 1898780 (1cf91c hex) >>>> ## Booting image at 82000000 ... >>>> Image Name: Linux-2.6.32-rc2-davinci1 >>>> Image Type: ARM Linux Kernel Image (uncompressed) >>>> Data Size: 1898716 Bytes = 1.8 MB >>>> Load Address: 80008000 >>>> Entry Point: 80008000 >>>> Verifying Checksum ... OK >>>> OK >>>> >>>> Starting kernel ... >>>> >>>> Uncompressing >>>> Linux........................................................................................................................... >>>> done, booting the kernel. >>>> >>>> console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=10.0.0.1:/home/kunal/xcaster/ingenient-bsp/rootfs/fs,udp,v3,rsize=4096,wsize=1400 >>>> ip=10.0.0.3:10.0.0.1:10.0.0.1:255.255.255.0:XCASTER5000::off mem=128M >>>> mtdparts=davinci-nand.0:96k(ubl),736k(uboot),64k(uboot-env),2m(kernel),61568k(app) >>>> eth=80:4C:EF:54:87:0A >>>> doing console init now >>>> finished console init >>>> >>>> /***************************************************************/ >>>> >>>> >>>> On Thu, Sep 30, 2010 at 6:26 PM, Raffaele Recalcati < >>>> lamiaposta71 at gmail.com> wrote: >>>> >>>>> On Thu, Sep 30, 2010 at 2:35 PM, kunal singh >>>>> wrote: >>>>> > Hi Raffaele, >>>>> > >>>>> > Thanks for the suggestion. >>>>> > >>>>> > (1) Console is fine. I am able to communicate with the u-boot >>>>> (115200,n8). >>>>> > Also if I use printascii (a kernel function) I am able to output on >>>>> console. >>>>> > (2) There is no message, after the kernel decompression (because >>>>> console is >>>>> > not up). Here is what I see. >>>>> > >>>>> > Load address: 0x82000000 >>>>> > Loading: ####T ###################T >>>>> > ########################################## >>>>> > >>>>> ################################################################## >>>>> > ######################T >>>>> > ############################################ >>>>> > >>>>> ################################################################# >>>>> > ###################T >>>>> > ##############################################T ## >>>>> > ######T ######################################## >>>>> > done >>>>> > Bytes transferred = 1898828 (1cf94c hex) >>>>> > ## Booting image at 82000000 ... >>>>> > Image Name: Linux-2.6.32-rc2-davinci1 >>>>> > Image Type: ARM Linux Kernel Image (uncompressed) >>>>> > Data Size: 1898764 Bytes = 1.8 MB >>>>> > Load Address: 80008000 >>>>> > Entry Point: 80008000 >>>>> > Verifying Checksum ... OK >>>>> > OK >>>>> > >>>>> > Starting kernel ... >>>>> > >>>>> > Uncompressing >>>>> > >>>>> Linux........................................................................................................................... >>>>> > done, booting the kernel. >>>>> > >>>>> > /* AND THEN NOTHING BECAUSE CONSOLE IS NOT FUNCTIONAL, but booting >>>>> goes on >>>>> > */ >>>>> >>>>> How can you say that boot goes on? >>>>> Can you check mem inside bootargs? >>>>> For instance I have 128MB RAM and I use these bootargs. >>>>> >>>>> set bootargs 'console=ttyS0,115200n8 rw >>>>> ip=10.39.10.183:10.39.10.169:10.39.8.1:255.255.248.0:::off >>>>> root=/dev/nfs nfsroot=10.39.10.169:/home/NFS/ARAGO_DEMO_IMAGE-raf/ >>>>> mem=128M video=davincifb:output=lcd:format=rgb:vid0=240x320 at 0 >>>>> ,0:vid1=240x320 at 0,0:osd0=240x320 at 0,0:osd1=240x320 at 0,0 >>>>> ' >>>>> >>>>> Don't copy my bootargs, only do some tests. >>>>> I saw your behaviour when mem was wrong. >>>>> >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lrg at slimlogic.co.uk Mon Oct 4 05:19:21 2010 From: lrg at slimlogic.co.uk (Liam Girdwood) Date: Mon, 04 Oct 2010 11:19:21 +0100 Subject: [alsa-devel] [PATCH 1/1] ALSA: ASoc: DaVinci Delay start of ASP to trigger In-Reply-To: <1286142259-6625-1-git-send-email-martin@ti.com> References: <1286142259-6625-1-git-send-email-martin@ti.com> Message-ID: <1286187561.3148.23.camel@odin> On Sun, 2010-10-03 at 16:44 -0500, martin at ti.com wrote: > From: Troy Kisky > > Since only 4 mainline ASoC codecs support the trigger > callback, we cannot rely upon them stopping the frame clock > if they are master and must assume it is running even if the > sound is paused. Thus we cannot start the ASP until the trigger > method. > > Signed-off-by: Troy Kisky > Signed-off-by: Martin Ambrose Acked-by: Liam Girdwood -- Freelance Developer, SlimLogic Ltd ASoC and Voltage Regulator Maintainer. http://www.slimlogic.co.uk From tobias.knutsson at gmail.com Mon Oct 4 06:33:12 2010 From: tobias.knutsson at gmail.com (Tobias Waldekranz) Date: Mon, 4 Oct 2010 13:33:12 +0200 Subject: Adding a library (libusb) to the toolchain for cross-compilation - Working with DM6446 In-Reply-To: References: Message-ID: On Thu, Sep 9, 2010 at 08:05, Arturo CV wrote: > Looking around to find a solution of why it didn't cross-compile properly I > found that the application uses the library "libusb", and this one is no > part of the Toolchain of the cross-compiler, so I was wondering if someone > can tell me How can I add this library into the toolchain so the > cross-compiler can find the headers that are missing? You will have to cross-compile libusb and then copy the library and header files to a location where your toolchain can locate them. In the case of CodeSourcery, you can put them in cs_root/arm-none-linux-gnueabi/lib and cs_root/arm-none-linux-gnueabi/include for example. You will also need the library on the target's root filesystem unless you link it statically, please mind the licencing implications if you do though. -- H?lsningar/Regards Tobias Waldekranz From khilman at deeprootsystems.com Mon Oct 4 09:47:59 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 04 Oct 2010 07:47:59 -0700 Subject: [PATCH v7] davinci: Initial support for Omapl138-Hawkboard In-Reply-To: <201010021800.52224.caglarakyuz@gmail.com> (Caglar Akyuz's message of "Sat, 2 Oct 2010 18:00:52 +0300") References: <1285259320-2541-1-git-send-email-vm.rod25@gmail.com> <87lj6rkxu2.fsf@deeprootsystems.com> <201010021800.52224.caglarakyuz@gmail.com> Message-ID: <87lj6e3tgg.fsf@deeprootsystems.com> Caglar Akyuz writes: > On Friday 24 September 2010 05:41:57 pm Kevin Hilman wrote: >> Victor Rodriguez writes: >> > This patch adds initial support for the Hawkboard-L138 system >> > It is under the machine name "omapl138_hawkboard". >> > This system is based on the da850 davinci CPU architecture. >> > Information on these system may be found at http://www.hawkboard.org. >> > Basic support for the UART console is included in this patch. >> > It's tested with latest Angstrom File Systems like ramdisk >> > from http://alturl.com/imb45. >> > >> > Signed-off-by: Victor Rodriguez >> > --- >> > Changes since v6: >> > 1) Change commit reference >> > 2) Remove hack that shut down UART1 because >> > it is unused at present on the hawkboard. >> >> Thanks for removing this. >> >> Applying and queuing for 2.6.37 in davinci-next. >> >> Kevin >> > > This commit is missing as of today. I can't see this in your tree, commit is > present but changes are not there. master branch has nothing related to Hawk. > > All changes are dissappearing after following commit: > > commit 3b910ca5eef70179ee4b2c9f195df6da4f402532 > Author: Michael Williamson > Date: Fri Sep 17 09:56:06 2010 -0400 > > davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom > > For the MityDSP-L138/MityARM-1808 SOMS, read the factory assigned > MAC address from the onboard I2C EPROM and assign it to the emac > device during platform initialization. > > Signed-off-by: Michael Williamson > Signed-off-by: Kevin Hilman > > arch/arm/mach-davinci/board-mityomapl138.c | 62 > 1 files changed, 62 insertions(+), 0 deletions(-) > > Am I missing something? Nope, I forgot to push the updated master branch. Sorry. Just pushed now (takes a little bit to propagate to all kernel.org mirrors.) Kevin From khilman at deeprootsystems.com Mon Oct 4 09:50:35 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 04 Oct 2010 07:50:35 -0700 Subject: [PATCH 5/5] arm/davinci: remove duplicated include In-Reply-To: <20101004123947.1e89128f@absol.kitzblitz> (Nicolas Kaiser's message of "Mon, 4 Oct 2010 12:39:47 +0200") References: <20101004122436.7092868f@absol.kitzblitz> <20101004123947.1e89128f@absol.kitzblitz> Message-ID: <87fwwm3tc4.fsf@deeprootsystems.com> Nicolas Kaiser writes: > Remove duplicated include. > > Signed-off-by: Nicolas Kaiser Applied, thanks. Queuing for 2.6.37. Kevin > --- > arch/arm/mach-davinci/board-da850-evm.c | 1 - > 1 files changed, 0 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c > index fdc2cc5..851cc45 100644 > --- a/arch/arm/mach-davinci/board-da850-evm.c > +++ b/arch/arm/mach-davinci/board-da850-evm.c > @@ -26,7 +26,6 @@ > #include > #include > #include > -#include > #include > > #include From vm.rod25 at gmail.com Mon Oct 4 15:24:03 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 4 Oct 2010 15:24:03 -0500 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard Message-ID: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..b22c275 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,55 @@ #include #include +#include + +#define DA850_EVM_PHY_ID "0:07" + +static const short omapl138_hawk_mii_pins[] = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static int __init omapl138_hawk_config_emac(void) +{ + void __iomem *cfg_chip3_base; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return 0; + + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfg_chip3_base); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + pr_info("EMAC: MII PHY configured, RMII PHY will not be" + " functional\n"); + + if (ret) + pr_warning("omapl138_hawk_init: " + "cpgmac/rmii mux setup failed: %d\n", ret); + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfg_chip3_base); + + /* Enable/Disable MII MDIO clock */ + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("omapl138_hawk_init: " + "emac registration failed: %d\n", ret); + return 0; +} +device_initcall(omapl138_hawk_config_emac); static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 4 19:00:56 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 4 Oct 2010 19:00:56 -0500 Subject: [PATCH v1] davinci: EDMA support for Omapl138-Hawkboard Message-ID: <1286236856-23042-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. EDMA support is necesary for SD/MMC and sound support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 55 +++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index b22c275..7e3fee4 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -69,6 +69,56 @@ static int __init omapl138_hawk_config_emac(void) } device_initcall(omapl138_hawk_config_emac); +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence + * they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -79,6 +129,11 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("omapl138_hawk_init: " + "edma registration failed: %d\n", ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From broonie at opensource.wolfsonmicro.com Mon Oct 4 19:55:20 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Tue, 5 Oct 2010 01:55:20 +0100 Subject: [PATCH 1/1] ALSA: ASoc: DaVinci Delay start of ASP to trigger In-Reply-To: <1286142259-6625-1-git-send-email-martin@ti.com> References: <1286142259-6625-1-git-send-email-martin@ti.com> Message-ID: <20101005005519.GB20773@sirena.org.uk> On Sun, Oct 03, 2010 at 04:44:19PM -0500, martin at ti.com wrote: > From: Troy Kisky > > Since only 4 mainline ASoC codecs support the trigger > callback, we cannot rely upon them stopping the frame clock > if they are master and must assume it is running even if the > sound is paused. Thus we cannot start the ASP until the trigger > method. Applied, thanks. From nsekhar at ti.com Mon Oct 4 23:51:51 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Tue, 5 Oct 2010 10:21:51 +0530 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> References: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> Message-ID: Hi Victor, On Tue, Oct 05, 2010 at 01:54:03, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > This patch adds EMAC support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ > 1 files changed, 49 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..b22c275 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,55 @@ > > #include > #include > +#include > + > +#define DA850_EVM_PHY_ID "0:07" > + > +static const short omapl138_hawk_mii_pins[] = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 > +}; Can this be marked as __initdata as it is only used in an __init function? Please watch out for section mismatch warnings while doing this. To get these warnings, just add "CONFIG_DEBUG_SECTION_MISMATCH=y" on your kernel build command. Also, I assume you are running these patches through 'sparse'. Just add C=1 to your kernel build command to enable sparse check. > + > +static int __init omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfg_chip3_base; > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info = &davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return 0; > + > + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + > + val = __raw_readl(cfg_chip3_base); > + > + val &= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + pr_info("EMAC: MII PHY configured, RMII PHY will not be" > + " functional\n"); Do we really have both MII and RMII phys on the hawk? Seems like only MII phy is being setup here. > + > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "cpgmac/rmii mux setup failed: %d\n", ret); > + > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfg_chip3_base); > + > + /* Enable/Disable MII MDIO clock */ Comment seems out of place? > + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; > + > + ret = da8xx_register_emac(); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "emac registration failed: %d\n", ret); You can use __func__ to avoid typing out the function name in the message. > + return 0; > +} > +device_initcall(omapl138_hawk_config_emac); I don't think you need to go the initcall way for initializing EMAC on hawk. I believe it was done this way on the EVM since EMAC init had a dependency on UI card detection using GPIO expander. Thanks, Sekhar From nsekhar at ti.com Tue Oct 5 00:09:33 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Tue, 5 Oct 2010 10:39:33 +0530 Subject: [PATCH v1] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1286236856-23042-1-git-send-email-vm.rod25@gmail.com> References: <1286236856-23042-1-git-send-email-vm.rod25@gmail.com> Message-ID: Hi Victor, On Tue, Oct 05, 2010 at 05:30:56, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > This patch adds EDMA support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > EDMA support is necesary for SD/MMC and sound support > > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 55 +++++++++++++++++++++++++++ > 1 files changed, 55 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index b22c275..7e3fee4 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -69,6 +69,56 @@ static int __init omapl138_hawk_config_emac(void) > } > device_initcall(omapl138_hawk_config_emac); Seems like this patch has a dependency on the EMAC patch submitted earlier. To convey this you can: 1) Generate the patches as a series so it is clear which patch to apply first (preferred). or 2) Note this dependency below the --- in the patch. Thanks, Sekhar From sugumar at ti.com Tue Oct 5 00:57:12 2010 From: sugumar at ti.com (Sugumar Natarajan) Date: Tue, 5 Oct 2010 11:27:12 +0530 Subject: [PATCH v5 1/4] davinci: Add generic PWM support for PWM control In-Reply-To: <8739sp7en7.fsf@deeprootsystems.com> References: <1284968386-16898-1-git-send-email-sugumar@ti.com> <8739sp7en7.fsf@deeprootsystems.com> Message-ID: <019d01cb6452$276557c0$76300740$@com> On Sat, Oct 02, 2010 at 03:35:16, Kevin Hilman wrote: > Sugumar Natarajan writes: > > > This patch adds generic PWM support where it maintains the list of PWM > > control devices that can be added or removed. > > > > The interface provides a list of functions that can be accessed by the > > PWM control driver module and the generic PWM driver. > > > > The PWM control driver module such as eCAP uses the interface to > > register and add itself to the list as a PWM control device. > > The generic PWM driver uses the interface to search for a PWM control > > device and if present, uses the device for PWM control. > > > > Signed-off-by: Sugumar Natarajan > > Sugumar, > > Would you mind having a look at a generic PWM layer that was recently proposed. Being familiar with the PWM needs on davinci, your feedback would be very valuable on this series. > > http://marc.info/?l=linux-embedded&r=1&b=201010&w=2 > > If we can adapt davinci usage to a more generic framework, that would be even better. > > Thanks, Kevin, It looks like a very good implementation. we can modify the driver to fit into the above framework. Also ,I am interested to see if the framework provides the flexibility to add features unique to some of the drivers such as eHRPWM. I want to first study the framework and then discuss with Bill Gatliff on this regard. So, I feel it better if I can discuss with him, review and modify the patches. Please give your say on this? > > Kevin > > From sshtylyov at mvista.com Tue Oct 5 04:32:09 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Tue, 05 Oct 2010 13:32:09 +0400 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> References: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CAAF099.8040800@mvista.com> Hello. On 05-10-2010 0:24, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds EMAC support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ > 1 files changed, 49 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..b22c275 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,55 @@ [...] > +static int __init omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfg_chip3_base; Why not just 'cfgchip3'? > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info =&davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return 0; > + > + cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + > + val = __raw_readl(cfg_chip3_base); > + > + val&= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + pr_info("EMAC: MII PHY configured, RMII PHY will not be" > + " functional\n"); > + > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "cpgmac/rmii mux setup failed: %d\n", ret); You're not configurign RMII, why mention it? > + > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfg_chip3_base); I'd first write CFGCHIP3, and then setup the PinMux... WBR, Sergei From sureshs at silvanlabs.com Tue Oct 5 05:40:06 2010 From: sureshs at silvanlabs.com (Suresh Somasekharappa) Date: Tue, 5 Oct 2010 16:10:06 +0530 Subject: Error while decoding using ./moduletest.out alg_vidDec Message-ID: Hi, I am getting the error while decoding a .264 file using moduletest.out. Environment: DM365 IPNC DVSDK Version: dvsdk_2_10_01_18 Error Details: ./moduletest.out alg_vidDec DRV_SyncRst: module = 47, domain = 0, state = 0 DRV_SyncRst: module = 47, domain = 0, state = 3 CLK Hz, ARM Hz = 432000000 DDR Hz = 340000000 VPSS Hz = 340000000 IMCOP Hz = 340000000 [OSA_FILE ] Reading file [/mnt/nand/IMG_Paramset.bin] ... ERROR IMAGE TUNE: Paramset File is not available..... Setting DEFAULT parameter [OSA_FILE ] Reading file [test.264] ... Done. [9869 bytes] ERROR (alg_vidDec.c|ALG_vidDecCreate|86): Failed to open video decode algorithm (h264dec) ERROR (alg_vidDec.c|ALG_vidDecTestMain|445): ALG_vidDecCreate() DRV_SyncRst: module = 47, domain = 0, state = 2 Any help would be greatly appreciated. Regards, Suresh -------------- next part -------------- An HTML attachment was scrubbed... URL: From Andreas.Gaer at baslerweb.com Tue Oct 5 06:38:13 2010 From: Andreas.Gaer at baslerweb.com (Andreas.Gaer at baslerweb.com) Date: Tue, 5 Oct 2010 13:38:13 +0200 Subject: [PATCH] davinci: Implement sched_clock() Message-ID: <1286278693-21122-1-git-send-email-Andreas.Gaer@baslerweb.com> From: Andreas Gaeer Overwrite the default implementation of sched_clock that is based on jiffies by something more precise. This improves timestamps in ftrace. Implementation is copied from OMAP platform code. Signed-off-by: Andreas Gaeer --- arch/arm/mach-davinci/time.c | 23 ++++++++++++++++++++++- 1 files changed, 22 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 0f21c36..9facd6f 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -272,15 +272,35 @@ static cycle_t read_cycles(struct clocksource *cs) return (cycles_t)timer32_read(t); } +/* + * Kernel assumes that sched_clock can be called early but may not have + * things ready yet. + */ +static cycle_t read_dummy(struct clocksource *cs) +{ + return 0; +} + + static struct clocksource clocksource_davinci = { .rating = 300, - .read = read_cycles, + .read = read_dummy, .mask = CLOCKSOURCE_MASK(32), .shift = 24, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; /* + * Overwrite weak default sched_clock with something more precise + */ +unsigned long long notrace sched_clock(void) +{ + const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); + return clocksource_cyc2ns(cyc, clocksource_davinci.mult, + clocksource_davinci.shift); +} + +/* * clockevent */ static int davinci_set_next_event(unsigned long cycles, @@ -377,6 +397,7 @@ static void __init davinci_timer_init(void) davinci_clock_tick_rate = clk_get_rate(timer_clk); /* setup clocksource */ + clocksource_davinci.read = read_cycles; clocksource_davinci.name = id_to_name[clocksource_id]; clocksource_davinci.mult = clocksource_khz2mult(davinci_clock_tick_rate/1000, -- 1.7.2.2 From khilman at deeprootsystems.com Tue Oct 5 09:40:57 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Tue, 05 Oct 2010 07:40:57 -0700 Subject: [PATCH v5 1/4] davinci: Add generic PWM support for PWM control In-Reply-To: <019d01cb6452$276557c0$76300740$@com> (Sugumar Natarajan's message of "Tue, 5 Oct 2010 11:27:12 +0530") References: <1284968386-16898-1-git-send-email-sugumar@ti.com> <8739sp7en7.fsf@deeprootsystems.com> <019d01cb6452$276557c0$76300740$@com> Message-ID: <87vd5gvh1i.fsf@deeprootsystems.com> "Sugumar Natarajan" writes: > On Sat, Oct 02, 2010 at 03:35:16, Kevin Hilman wrote: >> Sugumar Natarajan writes: >> >> > This patch adds generic PWM support where it maintains the list of PWM >> > control devices that can be added or removed. >> > >> > The interface provides a list of functions that can be accessed by the >> > PWM control driver module and the generic PWM driver. >> > >> > The PWM control driver module such as eCAP uses the interface to >> > register and add itself to the list as a PWM control device. >> > The generic PWM driver uses the interface to search for a PWM control >> > device and if present, uses the device for PWM control. >> > >> > Signed-off-by: Sugumar Natarajan >> >> Sugumar, >> >> Would you mind having a look at a generic PWM layer that was recently proposed. Being familiar with the PWM needs on davinci, > your feedback would be very valuable on this series. >> >> http://marc.info/?l=linux-embedded&r=1&b=201010&w=2 >> >> If we can adapt davinci usage to a more generic framework, that would be even better. >> >> Thanks, > > Kevin, It looks like a very good implementation. we can modify the > driver to fit into the above framework. Also ,I am interested to see > if the framework provides the flexibility to add features unique to > some of the drivers such as eHRPWM. I want to first study the > framework and then discuss with Bill Gatliff on this regard. So, I > feel it better if I can discuss with him, review and modify the > patches. Please give your say on this? I agree with your plan. His framework is currently posted as RFC, so he's looking for feedback and suggestions. Any areas where you feel that it wouldn't extend well for your needs, you should raise with him (I now see you've already responded on linux-embedded. Thanks!) Kevin From khilman at deeprootsystems.com Tue Oct 5 09:48:33 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Tue, 05 Oct 2010 07:48:33 -0700 Subject: [PATCH] davinci: Implement sched_clock() In-Reply-To: <1286278693-21122-1-git-send-email-Andreas.Gaer@baslerweb.com> (Andreas Gaer's message of "Tue, 5 Oct 2010 13:38:13 +0200") References: <1286278693-21122-1-git-send-email-Andreas.Gaer@baslerweb.com> Message-ID: <87k4lwvgou.fsf@deeprootsystems.com> Andreas.Gaer at baslerweb.com writes: > From: Andreas Gaeer > > Overwrite the default implementation of sched_clock that is based on > jiffies by something more precise. This improves timestamps in ftrace. > Implementation is copied from OMAP platform code. Very nice. thanks. After you fix some minor comments below, I will queue this for 2.6.37. > Signed-off-by: Andreas Gaeer > --- > arch/arm/mach-davinci/time.c | 23 ++++++++++++++++++++++- > 1 files changed, 22 insertions(+), 1 deletions(-) When sending kernel patches, please Cc the linux-arm-kernel mailing list: linux-arm-kernel at lists.infradead.org > diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c > index 0f21c36..9facd6f 100644 > --- a/arch/arm/mach-davinci/time.c > +++ b/arch/arm/mach-davinci/time.c > @@ -272,15 +272,35 @@ static cycle_t read_cycles(struct clocksource *cs) > return (cycles_t)timer32_read(t); > } > > +/* > + * Kernel assumes that sched_clock can be called early but may not have > + * things ready yet. > + */ > +static cycle_t read_dummy(struct clocksource *cs) > +{ > + return 0; > +} > + > + > static struct clocksource clocksource_davinci = { > .rating = 300, > - .read = read_cycles, > + .read = read_dummy, > .mask = CLOCKSOURCE_MASK(32), > .shift = 24, > .flags = CLOCK_SOURCE_IS_CONTINUOUS, > }; > > /* > + * Overwrite weak default sched_clock with something more precise > + */ > +unsigned long long notrace sched_clock(void) > +{ > + const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); insert blank line here > + return clocksource_cyc2ns(cyc, clocksource_davinci.mult, > + clocksource_davinci.shift); > +} > + > +/* > * clockevent > */ > static int davinci_set_next_event(unsigned long cycles, > @@ -377,6 +397,7 @@ static void __init davinci_timer_init(void) > davinci_clock_tick_rate = clk_get_rate(timer_clk); > > /* setup clocksource */ > + clocksource_davinci.read = read_cycles; > clocksource_davinci.name = id_to_name[clocksource_id]; > clocksource_davinci.mult = > clocksource_khz2mult(davinci_clock_tick_rate/1000, From cring at ti.com Tue Oct 5 11:00:00 2010 From: cring at ti.com (Ring, Chris) Date: Tue, 5 Oct 2010 11:00:00 -0500 Subject: Error while decoding using ./moduletest.out alg_vidDec In-Reply-To: References: Message-ID: <92CDD168D1E81F4F9D3839DC45903FC695F886FD@dlee03.ent.ti.com> I'm not familiar with this particular app, but if it's Codec Engine based (which is likely), you might find some clues by setting the env var CE_DEBUG=2 and re-running your app: http://processors.wiki.ti.com/index.php/CE_DEBUG Chris ________________________________ From: davinci-linux-open-source-bounces+cring=ti.com at linux.davincidsp.com [mailto:davinci-linux-open-source-bounces+cring=ti.com at linux.davincidsp.com] On Behalf Of Suresh Somasekharappa Sent: Tuesday, October 05, 2010 3:40 AM To: davinci-linux-open-source at linux.davincidsp.com Subject: Error while decoding using ./moduletest.out alg_vidDec Hi, I am getting the error while decoding a .264 file using moduletest.out. Environment: DM365 IPNC DVSDK Version: dvsdk_2_10_01_18 Error Details: ./moduletest.out alg_vidDec DRV_SyncRst: module = 47, domain = 0, state = 0 DRV_SyncRst: module = 47, domain = 0, state = 3 CLK Hz, ARM Hz = 432000000 DDR Hz = 340000000 VPSS Hz = 340000000 IMCOP Hz = 340000000 [OSA_FILE ] Reading file [/mnt/nand/IMG_Paramset.bin] ... ERROR IMAGE TUNE: Paramset File is not available..... Setting DEFAULT parameter [OSA_FILE ] Reading file [test.264] ... Done. [9869 bytes] ERROR (alg_vidDec.c|ALG_vidDecCreate|86): Failed to open video decode algorithm (h264dec) ERROR (alg_vidDec.c|ALG_vidDecTestMain|445): ALG_vidDecCreate() DRV_SyncRst: module = 47, domain = 0, state = 2 Any help would be greatly appreciated. Regards, Suresh -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Tue Oct 5 12:07:12 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Tue, 5 Oct 2010 12:07:12 -0500 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> Message-ID: On Mon, Oct 4, 2010 at 11:51 PM, Nori, Sekhar wrote: > > Hi Victor, > > On Tue, Oct 05, 2010 at 01:54:03, vm.rod25 at gmail.com wrote: > > From: Victor Rodriguez > > > > This patch adds EMAC support for the Hawkboard-L138 system > > It is under the machine name "omapl138_hawkboard". > > This system is based on the da850 davinci CPU architecture. > > > > Signed-off-by: Victor Rodriguez > > --- > > ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 49 +++++++++++++++++++++++++++ > > ?1 files changed, 49 insertions(+), 0 deletions(-) > > > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > > index c472dd8..b22c275 100644 > > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > @@ -19,6 +19,55 @@ > > > > ?#include > > ?#include > > +#include > > + > > +#define DA850_EVM_PHY_ID ? ? ? ? ? ? "0:07" > > + > > +static const short omapl138_hawk_mii_pins[] = { > > + ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > > + ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > > + ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > > + ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > > + ? ? DA850_MDIO_D, > > + ? ? -1 > > +}; > > Can this be marked as __initdata as it is only used in an __init function? > > Please watch out for section mismatch warnings while doing this. To get > these warnings, just add "CONFIG_DEBUG_SECTION_MISMATCH=y" on your kernel > build command. > > Also, I assume you are running these patches through 'sparse'. Just add C=1 > to your kernel build command to enable sparse check. > I have changed it to static short omapl138_hawk_mii_pins[] __initdata = { but still the same warning > > > + > > +static int __init omapl138_hawk_config_emac(void) > > +{ > > + ? ? void __iomem *cfg_chip3_base; > > + ? ? int ret; > > + ? ? u32 val; > > + ? ? struct davinci_soc_info *soc_info = &davinci_soc_info; > > + > > + ? ? if (!machine_is_omapl138_hawkboard()) > > + ? ? ? ? ? ? return 0; > > + > > + ? ? cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > > + > > + ? ? val = __raw_readl(cfg_chip3_base); > > + > > + ? ? val &= ~BIT(8); > > + ? ? ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > > + ? ? pr_info("EMAC: MII PHY configured, RMII PHY will not be" > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " functional\n"); > > Do we really have both MII and RMII phys on the hawk? Seems > like only MII phy is being setup here. Sorry for that I have changed to val &= ~BIT(8); ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); pr_info("EMAC: MII PHY configured\n"); > > + > > + ? ? if (ret) > > + ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " > > + ? ? ? ? ? ? ? ? ? ? "cpgmac/rmii mux setup failed: %d\n", ret); > > + > > + ? ? /* configure the CFGCHIP3 register for MII */ > > + ? ? __raw_writel(val, cfg_chip3_base); > > + > > + ? ? /* Enable/Disable MII MDIO clock */ > > Comment seems out of place? Thanks now is deleted > > + ? ? soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; > > + > > + ? ? ret = da8xx_register_emac(); > > + ? ? if (ret) > > + ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " > > + ? ? ? ? ? ? ? ? ? ? "emac registration failed: %d\n", ret); > > You can use __func__ to avoid typing out the function name in the > message. Changed to if (ret) pr_warning("%s: " "cpgmac/mii mux setup failed: %d\n",__func__, ret); /* configure the CFGCHIP3 register for MII */ __raw_writel(val, cfg_chip3_base); soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; ret = da8xx_register_emac(); if (ret) pr_warning("%s: " "emac registration failed: %d\n",__func__, ret); return 0; > > + ? ? return 0; > > +} > > +device_initcall(omapl138_hawk_config_emac); > > I don't think you need to go the initcall way for initializing EMAC > on hawk. I believe it was done this way on the EVM since EMAC init > had a dependency on UI card detection using GPIO expander. Yes you are right now i have just called the function like this static __init void omapl138_hawk_init(void) { int ret; davinci_serial_init(&omapl138_hawk_uart_config); ret = omapl138_hawk_config_emac(); ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " "watchdog registration failed: %d\n", ret); } Thanks Victor Rodriguez > Thanks, > Sekhar > From vm.rod25 at gmail.com Tue Oct 5 12:12:40 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Tue, 5 Oct 2010 12:12:40 -0500 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <4CAAF099.8040800@mvista.com> References: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> <4CAAF099.8040800@mvista.com> Message-ID: On Tue, Oct 5, 2010 at 4:32 AM, Sergei Shtylyov wrote: > Hello. > > On 05-10-2010 0:24, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds EMAC support for the Hawkboard-L138 system >> It is under the machine name "omapl138_hawkboard". >> This system is based on the da850 davinci CPU architecture. > >> Signed-off-by: Victor Rodriguez >> --- >> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 49 >> +++++++++++++++++++++++++++ >> ?1 files changed, 49 insertions(+), 0 deletions(-) >> >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index c472dd8..b22c275 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -19,6 +19,55 @@ > > [...] > >> +static int __init omapl138_hawk_config_emac(void) >> +{ >> + ? ? ? void __iomem *cfg_chip3_base; > > ? Why not just 'cfgchip3'? Because the board file arch/arm/mach-davinci/board-da850-evm.c has the same name I would like to have coherence because we said taht it is based on da850 architecture. >> + ? ? ? int ret; >> + ? ? ? u32 val; >> + ? ? ? struct davinci_soc_info *soc_info =&davinci_soc_info; >> + >> + ? ? ? if (!machine_is_omapl138_hawkboard()) >> + ? ? ? ? ? ? ? return 0; >> + >> + ? ? ? cfg_chip3_base = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); >> + >> + ? ? ? val = __raw_readl(cfg_chip3_base); >> + >> + ? ? ? val&= ~BIT(8); >> + ? ? ? ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); >> + ? ? ? pr_info("EMAC: MII PHY configured, RMII PHY will not be" >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? " functional\n"); >> + >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " >> + ? ? ? ? ? ? ? ? ? ? ? "cpgmac/rmii mux setup failed: %d\n", ret); > > ? You're not configurign RMII, why mention it? Yes right will be changed to if (ret) pr_warning("%s: " "cpgmac/mii mux setup failed: %d\n",__func__, ret); >> + >> + ? ? ? /* configure the CFGCHIP3 register for MII */ >> + ? ? ? __raw_writel(val, cfg_chip3_base); > > ? I'd first write CFGCHIP3, and then setup the PinMux... Yes but I want to have coherence with da850-evm.c, but if you consider that is a indispensable i could change. Thanks Victor Rodriguez > WBR, Sergei > From Andreas.Gaer at baslerweb.com Wed Oct 6 03:38:55 2010 From: Andreas.Gaer at baslerweb.com (Andreas.Gaer at baslerweb.com) Date: Wed, 6 Oct 2010 10:38:55 +0200 Subject: [PATCH] davinci: Implement sched_clock() Message-ID: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> From: Andreas Gaeer Overwrite the default implementation of sched_clock that is based on jiffies by something more precise. This improves timestamps in ftrace. Implementation is copied from OMAP platform code. Signed-off-by: Andreas Gaeer --- arch/arm/mach-davinci/time.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 0f21c36..5d1eea0 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -272,15 +272,36 @@ static cycle_t read_cycles(struct clocksource *cs) return (cycles_t)timer32_read(t); } +/* + * Kernel assumes that sched_clock can be called early but may not have + * things ready yet. + */ +static cycle_t read_dummy(struct clocksource *cs) +{ + return 0; +} + + static struct clocksource clocksource_davinci = { .rating = 300, - .read = read_cycles, + .read = read_dummy, .mask = CLOCKSOURCE_MASK(32), .shift = 24, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; /* + * Overwrite weak default sched_clock with something more precise + */ +unsigned long long notrace sched_clock(void) +{ + const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); + + return clocksource_cyc2ns(cyc, clocksource_davinci.mult, + clocksource_davinci.shift); +} + +/* * clockevent */ static int davinci_set_next_event(unsigned long cycles, @@ -377,6 +398,7 @@ static void __init davinci_timer_init(void) davinci_clock_tick_rate = clk_get_rate(timer_clk); /* setup clocksource */ + clocksource_davinci.read = read_cycles; clocksource_davinci.name = id_to_name[clocksource_id]; clocksource_davinci.mult = clocksource_khz2mult(davinci_clock_tick_rate/1000, -- 1.7.2.2 From nsekhar at ti.com Wed Oct 6 10:37:43 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Wed, 6 Oct 2010 21:07:43 +0530 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: <4C979D1D.1070707@criticallink.com> References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> Message-ID: Hi Mike, On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: > > Let me know if you want testing on the DMA portion of the patch (when your ready, of course). I just finished pushing the DMA related patches to the git branch[1]. I have not tested yet, but feel free to give it a go (maybe I will get lucky again!). Also, do you have patches adding SPI support for DA850 platform? I can include these patches on this branch so others who will be testing don?t have to repeat the work. Thanks, Sekhar [1] http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite From anshuman at ti.com Wed Oct 6 11:15:41 2010 From: anshuman at ti.com (Saxena, Anshuman) Date: Wed, 6 Oct 2010 21:45:41 +0530 Subject: Error while decoding using ./moduletest.out alg_vidDec In-Reply-To: References: Message-ID: <2A3DCF3DA181AD40BDE86A3150B27B6B035666B85A@dbde02.ent.ti.com> Hi Suresh, Can you please print the error code that is returned? Or atleast run the test with CE_DEBUG=3 so that we can look at the error code in the codec. I assume you have loaded the cmem.ko and edmak.ko modules. Regards, Anshuman ________________________________ From: davinci-linux-open-source-bounces+anshuman=ti.com at linux.davincidsp.com [mailto:davinci-linux-open-source-bounces+anshuman=ti.com at linux.davincidsp.com] On Behalf Of Suresh Somasekharappa Sent: Tuesday, October 05, 2010 4:10 PM To: davinci-linux-open-source at linux.davincidsp.com Subject: Error while decoding using ./moduletest.out alg_vidDec Hi, I am getting the error while decoding a .264 file using moduletest.out. Environment: DM365 IPNC DVSDK Version: dvsdk_2_10_01_18 Error Details: ./moduletest.out alg_vidDec DRV_SyncRst: module = 47, domain = 0, state = 0 DRV_SyncRst: module = 47, domain = 0, state = 3 CLK Hz, ARM Hz = 432000000 DDR Hz = 340000000 VPSS Hz = 340000000 IMCOP Hz = 340000000 [OSA_FILE ] Reading file [/mnt/nand/IMG_Paramset.bin] ... ERROR IMAGE TUNE: Paramset File is not available..... Setting DEFAULT parameter [OSA_FILE ] Reading file [test.264] ... Done. [9869 bytes] ERROR (alg_vidDec.c|ALG_vidDecCreate|86): Failed to open video decode algorithm (h264dec) ERROR (alg_vidDec.c|ALG_vidDecTestMain|445): ALG_vidDecCreate() DRV_SyncRst: module = 47, domain = 0, state = 2 Any help would be greatly appreciated. Regards, Suresh -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Wed Oct 6 15:24:04 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Wed, 6 Oct 2010 15:24:04 -0500 Subject: SATA support Message-ID: HI is there a SATA support on Linux Davinci like on Argo tree? I found commit number 97c18bdf on Argo tree the which gives USB and SATA support on that project with the simple function ret = da8xx_register_sata(); on the board files Is there something similar on the Davinci tree ? Thanks Sincerely yours Victor Rodriguez From arunthomasw at gmail.com Wed Oct 6 18:13:31 2010 From: arunthomasw at gmail.com (arun thomas whitchurch) Date: Wed, 6 Oct 2010 19:13:31 -0400 Subject: Copy to SD card gets stuck Message-ID: Hi, I am using the git kernel 2.6.30 on a dm6446 board based on the evm. I have a process copying files periodically over to a microSD card which has an ext3 filesystem. The copy rate is about 4 MB at a time followed by 40 seconds of sleep. When I have other processes also running on the board, which use about 40 % of the CPU on average, the copy call gets stuck after about 5 minutes. When I do a 'ps aux' I see that the copy is in an 'uninterruptible sleep state' : USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 9498 0.0 0.1 1452 376 pts/0 D+ 17:49 0:00 cp 1MBFile /mnt/usb/1.tst When I do a cat on /sys/class/mmcblk0/stat, the field indicating the number I/Os currently in progress is around 60 and does not come down. I am not able to kill the cp even with a SIGKILL. If I have no other processes running, I do not see this problem. I was able to recreate this issue, both on a 2GB microSD card and a 16GB microSDHC card. Is there any known issue with the SD/MMC driver which could be causing this? Do you think moving to the latest version kernel might fix this? Thanks, Arun -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.williamson at criticallink.com Wed Oct 6 22:55:14 2010 From: michael.williamson at criticallink.com (Michael Williamson) Date: Wed, 06 Oct 2010 23:55:14 -0400 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> Message-ID: <4CAD44A2.8080008@criticallink.com> Hi Sekhar, On 10/06/2010 11:37 AM, Nori, Sekhar wrote: > Hi Mike, > > On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: >> >> Let me know if you want testing on the DMA portion of the patch (when your ready, of course). > > I just finished pushing the DMA related patches to the git branch[1]. > I have not tested yet, but feel free to give it a go (maybe I will get > lucky again!). > > Also, do you have patches adding SPI support for DA850 platform? > I can include these patches on this branch so others who will be > testing don?t have to repeat the work. > > Thanks, > Sekhar > > [1] http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite > Great news. I'll try to give it a spin before the weekend. I do have a patch for the MityDSP-L138 (da850 based), I could propose a patch set for the da850-evm (both use the same SPI-NOR device, same SPI port and chip select). I need to separate it out from some other work, and I'm a little bleary eyed right now. It's pretty straightforward, though. We've also got a couple of other devices that we can tinker with as well (a couple of different SPI/CAN interface chips). I'll let you know what we find. Thanks for hammering this out. -Mike From Jon.Povey at racelogic.co.uk Thu Oct 7 03:39:31 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Thu, 7 Oct 2010 09:39:31 +0100 Subject: [PATCH v4] i2c: davinci: Fix race when setting up for TX In-Reply-To: <87wrq3l6m0.fsf@deeprootsystems.com> Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EE3EA57@Cloud.RL.local> Hi Ben, I am not on the i2c list but noticed this pull request: http://www.spinics.net/linux/lists/linux-i2c/msg04022.html I think you have the wrong (old) version of this patch in that branch, http://git.fluff.org/gitweb?p=bjdooks/linux.git;a=commitdiff;h=4bba0fd8d1c6d405df666e2573e1a1f917098be0 The correct v4 one from the start of this thread has more lines of patch and this commit message: >>>>> When setting up to transmit, a race exists between the ISR and >>>>> i2c_davinci_xfer_msg() trying to load the first byte and adjust >>>>> counters. This is mostly visible for transmits > 1 byte long. >>>>> >>>>> The hardware starts sending immediately that MDR.STT is set. IMR >>>>> trickery doesn't work because if we start sending, finish the >>>>> first byte and an XRDY event occurs before we load IMR to unmask >>>>> it, we never get an interrupt, and we timeout. >>>>> >>>>> Sudhakar Rajashekhara explains that at least OMAP-L138 requires >>>>> MDR mode settings before DXR for correct behaviour, so load MDR >>>>> first with STT cleared and later load again with STT set. >>>>> >>>>> Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 >>>>> >>>>> Signed-off-by: Jon Povey >>>>> CC: Sudhakar Rajashekhara >>>>> CC: Troy Kisky It also has some more acks and a tested, via Kevin: > Acked-by: Troy Kisky > Tested-by: Sudhakar Rajashekhara > Acked-by: Kevin Hilman -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From sshtylyov at mvista.com Thu Oct 7 04:55:05 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 07 Oct 2010 13:55:05 +0400 Subject: SATA support In-Reply-To: References: Message-ID: <4CAD98F9.9000007@mvista.com> Hello. On 07-10-2010 0:24, Victor Rodriguez wrote: > HI is there a SATA support on Linux Davinci like on Argo tree? I found > commit number 97c18bdf on Argo tree the which gives USB and SATA > support on that project with the simple function > ret = da8xx_register_sata(); Both USB and SATA support given with this function? :-O > on the board files > Is there something similar on the Davinci tree ? No. But recently AHCI driver has been split into the PCI and platform drivers, so the SATA support is possible now... WBR, Sergei From itayc at hotmail.com Thu Oct 7 05:46:58 2010 From: itayc at hotmail.com (Itay C) Date: Thu, 7 Oct 2010 10:46:58 +0000 Subject: OMAP3530 troubles - jittery video, performance In-Reply-To: References: Message-ID: Hi, I am attempting to write a video streamer on an OMAP3530 based Embest Devkit8000 board. My development environment is based on a patched stack named OMAP35x-PSP-SDK-linux-kernel-02.01.03.11-devkit8000-patch-2 and available at http://code.google.com/p/devkit8000/ . The software I am writing is supposed to capture video, encode to H.264 using Codec Engine and broadcast over the network in RTP format. My development starting point was with a capture-display loopback demo named saMmapLoopback (from OMAP35x-PSP-SDK-02.01.03.11/src/examples/examples.tar.gz), which opens the capture and display drivers, and loops input video back out to the LCD monitor. Then I added code to open the Codec Engine and create an instance of an H.264 encoder, using TI's codec supplied with the DVSDK. The first thing I wanted to do was prevent the need to copy the captured video frame to the encoder's input buffer. I tried to get the video capture driver to write the incoming data directly to the CMEM buffer used as the codec's input buffer. This turned out to be impossible, and confirmed by a post on TI's discussion forum which added that a new PSP version solves that problem (sorry, I can't find that post right now). In any case, upgrading to a new PSP is not possible at the moment as the whole software stack is patched by Embest for this board and upgrading anything manually will likely cause problems. When looking at the saMmapLoopback example I saw that it used a regular memcpy operation to copy the captured video frame to the display output buffer. So, I decided to use a similar memcpy to copy the video data to the encoder input buffer instead. This worked - but performed very badly. A quick benchmark confirmed that copying from the capture to the display buffer takes about 10 msec, while copying to the encoder buffer took 40 msec! So... QUESTION 1: Why is CPU access to CMEM memory space far slower than other memory? Is there a way to fix this problem? My solution to this problem was to use the Resizer to copy the frame, using the FrameCopy module of DMAI, with HW acceleration enabled. The next step was to packetize the compressed video to RTP and send it over the network. When this worked and the video was visible in a VLC/Quicktime window, however, the next problem came to light: there was a slight jitter in the video that occured once every few seconds. After a bit of investigation it seems that the captured video frame is corrupted. Instead of being comprised of two new fields, it is made from one old field (perhaps from 3 frames previously) and one newly captured field. Sometimes the problem affects two consecutive frames before the capture returns to normal. I have verified that it is a capture problem and not an encode problem, by enabling the loopback to the LCD monitor and seeing the same corruption on the monitor. It's also not a hardware problem, we have two boards and the problem happens on both. I have spent weeks trying many approaches to solving this problem. I have tried to pinpoint the problem by eliminating various processing stages in my program. At one point I was convinced that the H264 encoding was causing the problem. Then I thought that the RTP packetization was causing a problem because it was accessing the encoder output buffer (which is also CMEM memory - see question 1). At another point it seemed that sending packets out to the network (the call to "sendto") was causing the problem. I've also tried to play with scheduling parameters and thread priorities (the app is multi-threaded). After all the investigation, however, I haven't been able to nail a single factor that is causing the video glitches, and it only seems that the less actions are done, the less frequently the glitches occur. QUESTION 2: Why am I seeing glitches in incoming video? I have a gut feeling that answering Question 1 may solve Question 2, that's why I bring both issues here. Thanks in advance for any assistance. Note that I have raised this question on Embest's forums but received no response. -itay -------------- next part -------------- An HTML attachment was scrubbed... URL: From savinay.dharmappa at ti.com Thu Oct 7 06:31:14 2010 From: savinay.dharmappa at ti.com (Savinay Dharmappa) Date: Thu, 7 Oct 2010 17:01:14 +0530 Subject: [PATCH 1/2] mtd: NOR flash driver for OMAP-L137/AM17x Message-ID: <1286451074-12765-1-git-send-email-savinay.dharmappa@ti.com> From: David Griego OMAP-L137/AM17x has limited number of dedicated EMIFA address pins, enough to interface directly to an SDRAM. If a device such as an asynchronous flash needs to be attached to the EMIFA, then either GPIO pins or a chip select may be used to control the flash device's upper address lines. This patch adds support for the NOR flash on the OMAP-L137/ AM17x user interface daughter board using the latch-addr-flash MTD mapping driver which allows flashes to be partially physically addressed. The upper address lines are set by a board specific code which is a separate patch. Signed-off-by: Aleksey Makarov Signed-off-by: Sergei Shtylyov Signed-off-by: Savinay Dharmappa --- drivers/mtd/maps/Kconfig | 9 + drivers/mtd/maps/Makefile | 1 + drivers/mtd/maps/latch-addr-flash.c | 271 ++++++++++++++++++++++++++++++++++ include/linux/mtd/latch-addr-flash.h | 29 ++++ 4 files changed, 310 insertions(+), 0 deletions(-) create mode 100644 drivers/mtd/maps/latch-addr-flash.c create mode 100644 include/linux/mtd/latch-addr-flash.h diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 701d942..b794ea2 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -543,4 +543,13 @@ config MTD_PISMO When built as a module, it will be called pismo.ko +config MTD_LATCH_ADDR + tristate "Latch-assisted Flash Chip Support" + depends on MTD_COMPLEX_MAPPINGS + help + Map driver which allows flashes to be partially physically addressed + and have the upper address lines set by a board specific code. + + If compiled as a module, it will be called latch-addr-flash. + endmenu diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index f216bb5..35c3573 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -58,3 +58,4 @@ obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o obj-$(CONFIG_MTD_VMU) += vmu-flash.o obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o +obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o diff --git a/drivers/mtd/maps/latch-addr-flash.c b/drivers/mtd/maps/latch-addr-flash.c new file mode 100644 index 0000000..e3a7f91 --- /dev/null +++ b/drivers/mtd/maps/latch-addr-flash.c @@ -0,0 +1,271 @@ +/* + * Interface for NOR flash driver whose high address lines are latched + * + * Copyright 2000 Nicolas Pitre + * Copyright 2005-2008 Analog Devices Inc. + * Coyright (C) 2008 MontaVista Software, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "latch-addr-flash" + +struct latch_addr_flash_info { + struct mtd_info *mtd; + struct map_info map; + struct resource *res; + + void (*set_window)(unsigned long offset, void *data); + void *data; + + /* cache; could be found out of res */ + unsigned long win_mask; + + int nr_parts; + struct mtd_partition *parts; + + spinlock_t lock; +}; + +static map_word lf_read(struct map_info *map, unsigned long ofs) +{ + struct latch_addr_flash_info *info; + map_word datum; + + info = (struct latch_addr_flash_info *)map->map_priv_1; + + spin_lock(&info->lock); + + info->set_window(ofs, info->data); + datum = inline_map_read(map, info->win_mask & ofs); + + spin_unlock(&info->lock); + + return datum; +} + +static void lf_write(struct map_info *map, map_word datum, unsigned long ofs) +{ + struct latch_addr_flash_info *info; + + info = (struct latch_addr_flash_info *)map->map_priv_1; + + spin_lock(&info->lock); + + info->set_window(ofs, info->data); + inline_map_write(map, datum, info->win_mask & ofs); + + spin_unlock(&info->lock); +} + +static void lf_copy_from(struct map_info *map, void *to, + unsigned long from, ssize_t len) +{ + struct latch_addr_flash_info *info = + (struct latch_addr_flash_info *) map->map_priv_1; + unsigned n; + + while (len > 0) { + n = info->win_mask + 1 - (from & info->win_mask); + if (n > len) + n = len; + + spin_lock(&info->lock); + + info->set_window(from, info->data); + memcpy_fromio(to, map->virt + (from & info->win_mask), n); + + spin_unlock(&info->lock); + + to += n; + from += n; + len -= n; + } +} + +static const char *rom_probe_types[] = { "cfi_probe", NULL }; + +static const char *part_probe_types[] = { "cmdlinepart", NULL }; + +static int latch_addr_flash_remove(struct platform_device *dev) +{ + struct latch_addr_flash_info *info; + struct latch_addr_flash_data *latch_addr_data; + + info = platform_get_drvdata(dev); + if (info == NULL) + return 0; + platform_set_drvdata(dev, NULL); + + latch_addr_data = dev->dev.platform_data; + + if (info->mtd != NULL) { + if (mtd_has_partitions()) { + if (info->nr_parts) { + del_mtd_partitions(info->mtd); + kfree(info->parts); + } else if (latch_addr_data->nr_parts) { + del_mtd_partitions(info->mtd); + } else { + del_mtd_device(info->mtd); + } + } else { + del_mtd_device(info->mtd); + } + map_destroy(info->mtd); + } + + if (info->map.virt != NULL) + iounmap(info->map.virt); + + if (info->res != NULL) + release_mem_region(info->res->start, resource_size(info->res)); + + kfree(info); + + if (latch_addr_data->done) + latch_addr_data->done(latch_addr_data->data); + + return 0; +} + +static int __devinit latch_addr_flash_probe(struct platform_device *dev) +{ + struct latch_addr_flash_data *latch_addr_data; + struct latch_addr_flash_info *info; + resource_size_t win_base = dev->resource->start; + resource_size_t win_size = resource_size(dev->resource); + const char **probe_type; + int chipsel; + int err; + + latch_addr_data = dev->dev.platform_data; + if (latch_addr_data == NULL) + return -ENODEV; + + pr_notice("latch-addr platform flash device: %#llx byte " + "window at %#.8llx\n", + (unsigned long long)win_size, (unsigned long long)win_base); + + chipsel = dev->id; + + if (latch_addr_data->init) { + err = latch_addr_data->init(latch_addr_data->data, chipsel); + if (err != 0) + return err; + } + + info = kzalloc(sizeof(struct latch_addr_flash_info), GFP_KERNEL); + if (info == NULL) { + err = -ENOMEM; + goto done; + } + + platform_set_drvdata(dev, info); + + info->res = request_mem_region(win_base, win_size, DRIVER_NAME); + if (info->res == NULL) { + dev_err(&dev->dev, "Could not reserve memory region\n"); + err = -EBUSY; + goto free_info; + } + + info->map.name = DRIVER_NAME; + info->map.size = latch_addr_data->size; + info->map.bankwidth = latch_addr_data->width; + + info->map.phys = NO_XIP; + info->map.virt = ioremap(win_base, win_size); + if (!info->map.virt) { + err = -ENOMEM; + goto free_res; + } + + info->map.map_priv_1 = (unsigned long)info; + + info->map.read = lf_read; + info->map.copy_from = lf_copy_from; + info->map.write = lf_write; + info->set_window = latch_addr_data->set_window; + info->data = latch_addr_data->data; + info->win_mask = win_size - 1; + + spin_lock_init(&info->lock); + + for (probe_type = rom_probe_types; !info->mtd && *probe_type; + probe_type++) + info->mtd = do_map_probe(*probe_type, &info->map); + + if (info->mtd == NULL) { + dev_err(&dev->dev, "map_probe failed\n"); + err = -ENODEV; + goto iounmap; + } + info->mtd->owner = THIS_MODULE; + + if (mtd_has_partitions()) { + + err = parse_mtd_partitions(info->mtd, part_probe_types, + &info->parts, 0); + if (err > 0) { + add_mtd_partitions(info->mtd, info->parts, err); + return 0; + } + if (latch_addr_data->nr_parts) { + pr_notice("Using latch-addr-flash partition information\n"); + add_mtd_partitions(info->mtd, latch_addr_data->parts, + latch_addr_data->nr_parts); + return 0; + } + } + add_mtd_device(info->mtd); + return 0; + +iounmap: + iounmap(info->map.virt); +free_res: + release_mem_region(info->res->start, resource_size(info->res)); +free_info: + kfree(info); +done: + if (latch_addr_data->done) + latch_addr_data->done(latch_addr_data->data); + return err; +} + +static struct platform_driver latch_addr_flash_driver = { + .probe = latch_addr_flash_probe, + .remove = __devexit_p(latch_addr_flash_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init latch_addr_flash_init(void) +{ + return platform_driver_register(&latch_addr_flash_driver); +} +module_init(latch_addr_flash_init); + +static void __exit latch_addr_flash_exit(void) +{ + platform_driver_unregister(&latch_addr_flash_driver); +} +module_exit(latch_addr_flash_exit); + +MODULE_AUTHOR("David Griego "); +MODULE_DESCRIPTION("MTD map driver for flashes addressed physically with upper " + "address lines being set board specifically"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mtd/latch-addr-flash.h b/include/linux/mtd/latch-addr-flash.h new file mode 100644 index 0000000..c77e7c9 --- /dev/null +++ b/include/linux/mtd/latch-addr-flash.h @@ -0,0 +1,29 @@ +/* + * Interface for NOR flash driver whose high address lines are latched + * + * Copyright (C) 2008 MontaVista Software, Inc. + * + * This file is licensed underthe terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef __LATCH_ADDR_FLASH__ +#define __LATCH_ADDR_FLASH__ + +struct map_info; +struct mtd_partition; + +struct latch_addr_flash_data { + unsigned int width; + unsigned int size; + + int (*init)(void *data, int cs); + void (*done)(void *data); + void (*set_window)(unsigned long offset, void *data); + void *data; + + unsigned int nr_parts; + struct mtd_partition *parts; +}; + +#endif -- 1.5.6 From savinay.dharmappa at ti.com Thu Oct 7 06:34:32 2010 From: savinay.dharmappa at ti.com (Savinay Dharmappa) Date: Thu, 7 Oct 2010 17:04:32 +0530 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver Message-ID: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> From: David Griego Adds platform support for OMAP-L137/AM17x NOR flash driver. Also, configures chip select 3 to control NOR flash's upper address lines. Signed-off-by: Aleksey Makarov Signed-off-by: Sergei Shtylyov Signed-off-by: Savinay Dharmappa --- arch/arm/mach-davinci/Kconfig | 8 + arch/arm/mach-davinci/board-da830-evm.c | 224 +++++++++++++++++++++++++++++++ 2 files changed, 232 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index 9aca60c..baa39ee 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -142,6 +142,14 @@ config DA830_UI_NAND help Say Y here to use the NAND flash. Do not forget to setup the switch correctly. + +config DA830_UI_NOR + bool "NOR flash" + help + Configure this option to specify the that AEMIF CE2/CE3 will be used to + communicate to the NOR flash. Do not forget to setup the switch SW1 + on UI card correctly. + endchoice config MACH_DAVINCI_DA850_EVM diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index 1bb89d3..9f18efc 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -429,6 +431,226 @@ static inline void da830_evm_init_nand(int mux_mode) static inline void da830_evm_init_nand(int mux_mode) { } #endif +#ifdef CONFIG_DA830_UI_NOR +/* + * Number of Address line going to the NOR flash that are latched using + * AEMIF address lines B_EMIF_BA0-B_EMIF_A12 on CS2. + */ +#define NOR_WINDOW_SIZE_LOG2 15 +#define NOR_WINDOW_SIZE (1 << NOR_WINDOW_SIZE_LOG2) + +static struct { + struct clk *clk; + struct { + struct resource *res; + void __iomem *addr; + } latch, aemif; +} da830_evm_nor; + +static struct davinci_aemif_timing da830_evm_norflash_timing = { + .wsetup = 0, + .wstrobe = 40, + .whold = 0, + .rsetup = 0, + .rstrobe = 130, + .rhold = 0, + .ta = 20, +}; + +static void da830_evm_nor_set_window(unsigned long offset, void *data) +{ + /* + * CS2 and CS3 address lines are used to address nor flash. Address + * line A0-A14 going to the NOR flash are latched using AEMIF address + * lines B_EMIF_BA0-B_EMIF_A12 on CS2. Address lines A15-A23 of the + * NOR flash are latched using AEMIF address lines B_EMIF_A0-B_EMIF_A6 + * on CS3. The offset argument received by this function is the offset + * within NOR flash. Upper address is obtained by shifting the offset + * by the number of CS2 address lines used (13) and masking it with + * complement of 3 (2 address lines used to address banks) and adding + * the resultant offset value to CS3 base address. Writing a zero to + * this address will latch the upper address lines. + */ + writeb(0, da830_evm_nor.latch.addr + + (~3UL & (offset >> (NOR_WINDOW_SIZE_LOG2 - 2)))); +} + +static void da830_evm_nor_done(void *data) +{ + clk_disable(da830_evm_nor.clk); + clk_put(da830_evm_nor.clk); + iounmap(da830_evm_nor.latch.addr); + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); + iounmap(da830_evm_nor.aemif.addr); + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); +} + +static int da830_evm_nor_init(void *data, int cs) +{ + /* Turn on AEMIF clocks */ + da830_evm_nor.clk = clk_get(NULL, "aemif"); + if (IS_ERR(da830_evm_nor.clk)) { + pr_err("%s: could not get AEMIF clock\n", __func__); + da830_evm_nor.clk = NULL; + return -ENODEV; + } + clk_enable(da830_evm_nor.clk); + + da830_evm_nor.aemif.res = request_mem_region(DA8XX_AEMIF_CTL_BASE, + SZ_32K, "AEMIF control"); + if (da830_evm_nor.aemif.res == NULL) { + pr_err("%s: could not request AEMIF control region\n", + __func__); + goto err_aemif_region; + } + + da830_evm_nor.aemif.addr = ioremap_nocache(DA8XX_AEMIF_CTL_BASE, + SZ_32K); + if (da830_evm_nor.aemif.addr == NULL) { + pr_err("%s: could not remap AEMIF control region\n", __func__); + goto err_aemif_ioremap; + } + + /* Setup AEMIF -- timings, etc. */ + + /* Set maximum wait cycles */ + davinci_aemif_setup_timing(&da830_evm_norflash_timing, + da830_evm_nor.aemif.addr, cs); + + davinci_aemif_setup_timing(&da830_evm_norflash_timing, + da830_evm_nor.aemif.addr, cs + 1); + + /* Setup the window to access the latch */ + da830_evm_nor.latch.res = + request_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE, + "DA830 UI NOR address latch"); + if (da830_evm_nor.latch.res == NULL) { + pr_err("%s: could not request address latch region\n", + __func__); + goto err_latch_region; + } + + da830_evm_nor.latch.addr = + ioremap_nocache(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); + if (da830_evm_nor.latch.addr == NULL) { + pr_err("%s: could not remap address latch region\n", __func__); + goto err_latch_ioremap; + } + return 0; + +err_aemif_region: + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); + da830_evm_nor.aemif.res = NULL; + return -EBUSY; + +err_aemif_ioremap: + iounmap(da830_evm_nor.aemif.addr); + da830_evm_nor.aemif.addr = NULL; + return -ENOMEM; + +err_latch_region: + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); + da830_evm_nor.latch.res = NULL; + return -EBUSY; + +err_latch_ioremap: + iounmap(da830_evm_nor.latch.addr); + da830_evm_nor.latch.addr = NULL; + return -ENOMEM; +} + +static struct mtd_partition da830_evm_nor_partitions[] = { + /* bootloader (U-Boot, etc) in first 2 sectors */ + [0] = { + .name = "bootloader", + .offset = 0, + .size = SZ_128K, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + /* bootloader parameters in the next 1 sector */ + [1] = { + .name = "params", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + }, + /* kernel */ + [2] = { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M, + }, + /* file system */ + [3] = { + .name = "filesystem", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + } +}; + +static struct latch_addr_flash_data da830_evm_nor_pdata = { + .width = 1, + .size = SZ_4M, + .init = da830_evm_nor_init, + .done = da830_evm_nor_done, + .set_window = da830_evm_nor_set_window, + .nr_parts = ARRAY_SIZE(da830_evm_nor_partitions), + .parts = da830_evm_nor_partitions, +}; + +static struct resource da830_evm_nor_resource[] = { + [0] = { + .start = DA8XX_AEMIF_CS2_BASE, + .end = DA8XX_AEMIF_CS2_BASE + NOR_WINDOW_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DA8XX_AEMIF_CS3_BASE, + .end = DA8XX_AEMIF_CS3_BASE + PAGE_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = DA8XX_AEMIF_CTL_BASE, + .end = DA8XX_AEMIF_CTL_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device da830_evm_nor_device = { + .name = "latch-addr-flash", + .id = 0, + .dev = { + .platform_data = &da830_evm_nor_pdata, + }, + .num_resources = ARRAY_SIZE(da830_evm_nor_resource), + .resource = da830_evm_nor_resource, +}; + +static inline void da830_evm_init_nor(int mux_mode) +{ + int ret; + + if (HAS_MMC) { + pr_warning("WARNING: both MMC/SD and NOR are " + "enabled, but they share AEMIF pins.\n" + "\tDisable MMC/SD for NOR support.\n"); + return; + } + + ret = davinci_cfg_reg_list(da830_evm_emif25_pins); + if (ret) + pr_warning("da830_evm_init: emif25 mux setup failed: %d\n", + ret); + + ret = platform_device_register(&da830_evm_nor_device); + if (ret) + pr_warning("da830_evm_init: NOR device not registered.\n"); + + gpio_direction_output(mux_mode, 1); +} +#else +static inline void da830_evm_init_nor(int mux_mode) { } +#endif /* CONFIG_DA830_UI_NOR */ + #ifdef CONFIG_DA830_UI_LCD static inline void da830_evm_init_lcdc(int mux_mode) { @@ -469,6 +691,8 @@ static int __init da830_evm_ui_expander_setup(struct i2c_client *client, da830_evm_init_nand(gpio + 6); + da830_evm_init_nor(gpio + 6); + return 0; } -- 1.5.6 From mrybczynski at miovision.com Thu Oct 7 08:39:10 2010 From: mrybczynski at miovision.com (Mitch Rybczynski) Date: Thu, 7 Oct 2010 09:39:10 -0400 Subject: Davinci-linux-open-source Digest, Vol 58, Issue 22 In-Reply-To: References: Message-ID: Hi Arun, Not exactly DM6446 related, but maybe of historical interest: We've seen similar SD card issues with the older davinci TMS320DM320 part, with kernel 2.6.15, where at a certain point write access to a SD card will "Hang". In our case, in addition, any subsequent access to the filesystem of the card will hang as well. We've straced various applications, and whatever system call stats the card never returns. There is usually extra debug information you can turn on in the driver source, and recompile the kernel and check the output. In our case, it did not help, and we're still hanging intermittently without a workaround. Regards, Mitch > Date: Wed, 6 Oct 2010 19:13:31 -0400 > From: arun thomas whitchurch > To: davinci-linux-open-source at linux.davincidsp.com > Subject: Copy to SD card gets stuck > Message-ID: > ? ? ? ? > Content-Type: text/plain; charset="iso-8859-1" > > Hi, > I am using the git kernel 2.6.30 on a dm6446 board based on the evm. I have > a process copying files periodically over to a microSD card which has an > ext3 filesystem. The copy rate is about 4 MB at a time followed by 40 > seconds of sleep. When I have other processes also running on the board, > which use about 40 % of the CPU on average, the copy call gets stuck after > about 5 minutes. When I do a 'ps aux' I see that the copy is in an > 'uninterruptible sleep state' : > > USER ? ? ? PID %CPU %MEM ? ?VSZ ? RSS TTY ? ? ?STAT START ? TIME COMMAND > root ? ? ? ? ? 9498 ?0.0 ? ? ?0.1 ? ? ? ? 1452 ? 376 ? pts/0 ? ?D+ > ?17:49 ? ? 0:00 cp 1MBFile /mnt/usb/1.tst > > When I do a cat on /sys/class/mmcblk0/stat, the field indicating the number > I/Os currently in progress is around 60 and does not come down. I am not > able to kill the cp even with a SIGKILL. > > If I have no other processes running, I do not see this problem. I was able > to recreate this issue, both on a 2GB microSD card and a 16GB microSDHC > card. > > Is there any known issue with the SD/MMC driver which could be causing this? > Do you think moving to the latest version kernel might fix this? > > Thanks, > Arun -- Mitch Rybczynski, BSc Software Developer, Embedded Miovision Technologies Inc. www.miovision.com mrybczynski at miovision.com phone 519.513.2407 / 877.646.8476 fax 866.413.2928 From vm.rod25 at gmail.com Thu Oct 7 09:26:45 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 7 Oct 2010 09:26:45 -0500 Subject: SATA support In-Reply-To: References: <4CAD98F9.9000007@mvista.com> Message-ID: On Thu, Oct 7, 2010 at 9:25 AM, Victor Rodriguez wrote: > On Thu, Oct 7, 2010 at 4:55 AM, Sergei Shtylyov wrote: >> Hello. >> >> On 07-10-2010 0:24, Victor Rodriguez wrote: >> >>> HI is there a SATA support on Linux Davinci like on Argo tree? I found >>> commit number 97c18bdf on Argo tree the which gives USB and SATA >>> support on that project with the simple function >> >>> ? ? ? ?ret = da8xx_register_sata(); >> >> ? Both USB and SATA support given with this function? :-O > NO sorry for the error just SATA i already have USB working and is not as simple :-) >>> on the board files >> >>> Is there something similar on the Davinci tree ? >> >> ? No. But recently AHCI driver has been split into the PCI and platform >> drivers, so the SATA support is possible now... > > Do you think that is a good idea to give SATA support for Davinci ? I have some free time :) > > Regards > > Victor Rodriguez > > >> WBR, Sergei >> > From swami.iyer at ti.com Thu Oct 7 09:36:08 2010 From: swami.iyer at ti.com (Subbrathnam, Swaminathan) Date: Thu, 7 Oct 2010 20:06:08 +0530 Subject: SATA support In-Reply-To: References: <4CAD98F9.9000007@mvista.com> Message-ID: Victor, SATA is already supported on the OMAPL Arago tree. Regards swami > -----Original Message----- > From: davinci-linux-open-source-bounces at linux.davincidsp.com > [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf > Of Victor Rodriguez > Sent: Thursday, October 07, 2010 7:57 PM > To: davinci-linux-open-source at linux.davincidsp.com > Subject: Re: SATA support > > On Thu, Oct 7, 2010 at 9:25 AM, Victor Rodriguez > wrote: > > On Thu, Oct 7, 2010 at 4:55 AM, Sergei Shtylyov > wrote: > >> Hello. > >> > >> On 07-10-2010 0:24, Victor Rodriguez wrote: > >> > >>> HI is there a SATA support on Linux Davinci like on Argo tree? I found > >>> commit number 97c18bdf on Argo tree the which gives USB and SATA > >>> support on that project with the simple function > >> > >>> ? ? ? ?ret = da8xx_register_sata(); > >> > >> ? Both USB and SATA support given with this function? :-O > > > > NO sorry for the error just SATA i already have USB working and is > not as simple :-) > > > >>> on the board files > >> > >>> Is there something similar on the Davinci tree ? > >> > >> ? No. But recently AHCI driver has been split into the PCI and platform > >> drivers, so the SATA support is possible now... > > > > > Do you think that is a good idea to give SATA support for Davinci ? > I have some free time :) > > > > Regards > > > > Victor Rodriguez > > > > > >> WBR, Sergei > >> > > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From vm.rod25 at gmail.com Thu Oct 7 09:48:52 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 7 Oct 2010 09:48:52 -0500 Subject: SATA support In-Reply-To: References: <4CAD98F9.9000007@mvista.com> Message-ID: On Thu, Oct 7, 2010 at 9:36 AM, Subbrathnam, Swaminathan wrote: > Victor, > ? ? ? ?SATA is already supported on the OMAPL Arago tree. > > Regards > swami Yes I know but now that Hawkboard/OmapL-138 is on mainline I am working on all the patches in order to give complete support to the Hawkboard. SATA was the only that I did not find reference on mainline, Sergei commented me that would be a good idea to enable SATA to DA850 which is the only one that support SATA besides the Hawkboard I could use commit number 97c18bdf from Argo tree has reference What do you think ? Regards Victor Rodriguez >> -----Original Message----- >> From: davinci-linux-open-source-bounces at linux.davincidsp.com >> [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf >> Of Victor Rodriguez >> Sent: Thursday, October 07, 2010 7:57 PM >> To: davinci-linux-open-source at linux.davincidsp.com >> Subject: Re: SATA support >> >> On Thu, Oct 7, 2010 at 9:25 AM, Victor Rodriguez >> wrote: >> > On Thu, Oct 7, 2010 at 4:55 AM, Sergei Shtylyov >> wrote: >> >> Hello. >> >> >> >> On 07-10-2010 0:24, Victor Rodriguez wrote: >> >> >> >>> HI is there a SATA support on Linux Davinci like on Argo tree? I found >> >>> commit number 97c18bdf on Argo tree the which gives USB and SATA >> >>> support on that project with the simple function >> >> >> >>> ? ? ? ?ret = da8xx_register_sata(); >> >> >> >> ? Both USB and SATA support given with this function? :-O >> > >> >> NO sorry for the error just SATA i already have USB working and is >> ?not as simple :-) >> >> >> >>> on the board files >> >> >> >>> Is there something similar on the Davinci tree ? >> >> >> >> ? No. But recently AHCI driver has been split into the PCI and platform >> >> drivers, so the SATA support is possible now... >> > >> > >> Do ?you think that is a good idea to give SATA support for Davinci ? >> ?I have some free time :) >> > >> > Regards >> > >> > Victor Rodriguez >> > >> > >> >> WBR, Sergei >> >> >> > >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > From sshtylyov at mvista.com Thu Oct 7 10:05:28 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 07 Oct 2010 19:05:28 +0400 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> Message-ID: <4CADE1B8.50800@mvista.com> Hello. Savinay Dharmappa wrote: > From: David Griego And that's after I have told you this code is not authored by David, but by Aleksey Makarov... :-( > Adds platform support for OMAP-L137/AM17x NOR flash driver. > Also, configures chip select 3 to control NOR flash's upper > address lines. > Signed-off-by: Aleksey Makarov > Signed-off-by: Sergei Shtylyov > Signed-off-by: Savinay Dharmappa Moreover, I'm seeing that you've done some incorrect changes to the previously correct code. NAK. [...] > config MACH_DAVINCI_DA850_EVM > diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c > index 1bb89d3..9f18efc 100644 > --- a/arch/arm/mach-davinci/board-da830-evm.c > +++ b/arch/arm/mach-davinci/board-da830-evm.c [...] > @@ -429,6 +431,226 @@ static inline void da830_evm_init_nand(int mux_mode) [...] > +static void da830_evm_nor_done(void *data) > +{ > + clk_disable(da830_evm_nor.clk); > + clk_put(da830_evm_nor.clk); > + iounmap(da830_evm_nor.latch.addr); > + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > + iounmap(da830_evm_nor.aemif.addr); > + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); > +} Why you've changed this function which was useful also for the error cleanup before? > +static int da830_evm_nor_init(void *data, int cs) > +{ > + /* Turn on AEMIF clocks */ > + da830_evm_nor.clk = clk_get(NULL, "aemif"); > + if (IS_ERR(da830_evm_nor.clk)) { > + pr_err("%s: could not get AEMIF clock\n", __func__); > + da830_evm_nor.clk = NULL; > + return -ENODEV; > + } > + clk_enable(da830_evm_nor.clk); > + > + da830_evm_nor.aemif.res = request_mem_region(DA8XX_AEMIF_CTL_BASE, > + SZ_32K, "AEMIF control"); > + if (da830_evm_nor.aemif.res == NULL) { > + pr_err("%s: could not request AEMIF control region\n", > + __func__); > + goto err_aemif_region; I wonder why you used goto's at all. Anyway, the error cleanup code is completely broken now. > + } > + > + da830_evm_nor.aemif.addr = ioremap_nocache(DA8XX_AEMIF_CTL_BASE, > + SZ_32K); > + if (da830_evm_nor.aemif.addr == NULL) { > + pr_err("%s: could not remap AEMIF control region\n", __func__); > + goto err_aemif_ioremap; > + } > + > + /* Setup AEMIF -- timings, etc. */ > + > + /* Set maximum wait cycles */ > + davinci_aemif_setup_timing(&da830_evm_norflash_timing, > + da830_evm_nor.aemif.addr, cs); > + > + davinci_aemif_setup_timing(&da830_evm_norflash_timing, > + da830_evm_nor.aemif.addr, cs + 1); > + > + /* Setup the window to access the latch */ > + da830_evm_nor.latch.res = > + request_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE, > + "DA830 UI NOR address latch"); > + if (da830_evm_nor.latch.res == NULL) { > + pr_err("%s: could not request address latch region\n", > + __func__); > + goto err_latch_region; > + } > + > + da830_evm_nor.latch.addr = > + ioremap_nocache(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > + if (da830_evm_nor.latch.addr == NULL) { > + pr_err("%s: could not remap address latch region\n", __func__); > + goto err_latch_ioremap; > + } > + return 0; > + > +err_aemif_region: > + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); Why release what you've just failed to request?! > + da830_evm_nor.aemif.res = NULL; Useless assignment. > + return -EBUSY; And you're not calling clk_disable(). > +err_aemif_ioremap: > + iounmap(da830_evm_nor.aemif.addr); Why unmap what you've just failed to map?! da830_evm_nor.aemif.addr is NULL. > + da830_evm_nor.aemif.addr = NULL; Useless assignment. > + return -ENOMEM; You're not calling release_mem_region() and clk_disable(). > +err_latch_region: > + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); Why release what you've just failed to request?! > + da830_evm_nor.latch.res = NULL; Useless assginment. > + return -EBUSY; You're not calling iounmap() and release_mem_region() for the NOR flash region and also not calling clk_disable(). > + > +err_latch_ioremap: > + iounmap(da830_evm_nor.latch.addr); Why unmap what you've just failed to map?! da830_evm_nor.latch.addr is NULL. > + da830_evm_nor.latch.addr = NULL; Useless assginment. > + return -ENOMEM; You're not release_mem_region() for the latch region, not calling iounmap() and release_mem_region() for the NOR flash region and also not calling clk_disable(). > +} [...] Your changes made me doubt that you actually understood the code well enough before doing them... WBR, Sergei From khilman at deeprootsystems.com Thu Oct 7 12:01:53 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 07 Oct 2010 10:01:53 -0700 Subject: [PATCH v4] i2c: davinci: Fix race when setting up for TX In-Reply-To: <70E876B0EA86DD4BAF101844BC814DFE093EE3EA57@Cloud.RL.local> (Jon Povey's message of "Thu, 7 Oct 2010 09:39:31 +0100") References: <70E876B0EA86DD4BAF101844BC814DFE093EE3EA57@Cloud.RL.local> Message-ID: <87wrpu9bsu.fsf@deeprootsystems.com> Jon Povey writes: > Hi Ben, > > I am not on the i2c list but noticed this pull request: > http://www.spinics.net/linux/lists/linux-i2c/msg04022.html > > I think you have the wrong (old) version of this patch in that branch, > http://git.fluff.org/gitweb?p=bjdooks/linux.git;a=commitdiff;h=4bba0fd8d1c6d405df666e2573e1a1f917098be0 > > The correct v4 one from the start of this thread has more lines > of patch and this commit message: It is also available in my davinci-i2c branch: git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git davinci-i2c Thanks Jon for catching this, Kevin >>>>>> When setting up to transmit, a race exists between the ISR and >>>>>> i2c_davinci_xfer_msg() trying to load the first byte and adjust >>>>>> counters. This is mostly visible for transmits > 1 byte long. >>>>>> >>>>>> The hardware starts sending immediately that MDR.STT is set. IMR >>>>>> trickery doesn't work because if we start sending, finish the >>>>>> first byte and an XRDY event occurs before we load IMR to unmask >>>>>> it, we never get an interrupt, and we timeout. >>>>>> >>>>>> Sudhakar Rajashekhara explains that at least OMAP-L138 requires >>>>>> MDR mode settings before DXR for correct behaviour, so load MDR >>>>>> first with STT cleared and later load again with STT set. >>>>>> >>>>>> Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 >>>>>> >>>>>> Signed-off-by: Jon Povey >>>>>> CC: Sudhakar Rajashekhara >>>>>> CC: Troy Kisky > > It also has some more acks and a tested, via Kevin: > >> Acked-by: Troy Kisky >> Tested-by: Sudhakar Rajashekhara >> Acked-by: Kevin Hilman > > > -- > Jon Povey > jon.povey at racelogic.co.uk > > Racelogic is a limited company registered in England. Registered number 2743719 . > Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . > > The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From khilman at deeprootsystems.com Thu Oct 7 12:12:04 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 07 Oct 2010 10:12:04 -0700 Subject: [PATCH] davinci: Implement sched_clock() In-Reply-To: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> (Andreas Gaer's message of "Wed, 6 Oct 2010 10:38:55 +0200") References: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> Message-ID: <87pqvm9bbv.fsf@deeprootsystems.com> Andreas.Gaer at baslerweb.com writes: > From: Andreas Gaeer > > Overwrite the default implementation of sched_clock that is based on > jiffies by something more precise. This improves timestamps in ftrace. > Implementation is copied from OMAP platform code. > > Signed-off-by: Andreas Gaeer Thanks, applying to davinci git. Will queue for 2.6.38 (it's a bit too late for 2.6.37 as Linus only wants real regression fixes after -rc6.) Kevin > --- > arch/arm/mach-davinci/time.c | 24 +++++++++++++++++++++++- > 1 files changed, 23 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c > index 0f21c36..5d1eea0 100644 > --- a/arch/arm/mach-davinci/time.c > +++ b/arch/arm/mach-davinci/time.c > @@ -272,15 +272,36 @@ static cycle_t read_cycles(struct clocksource *cs) > return (cycles_t)timer32_read(t); > } > > +/* > + * Kernel assumes that sched_clock can be called early but may not have > + * things ready yet. > + */ > +static cycle_t read_dummy(struct clocksource *cs) > +{ > + return 0; > +} > + > + > static struct clocksource clocksource_davinci = { > .rating = 300, > - .read = read_cycles, > + .read = read_dummy, > .mask = CLOCKSOURCE_MASK(32), > .shift = 24, > .flags = CLOCK_SOURCE_IS_CONTINUOUS, > }; > > /* > + * Overwrite weak default sched_clock with something more precise > + */ > +unsigned long long notrace sched_clock(void) > +{ > + const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); > + > + return clocksource_cyc2ns(cyc, clocksource_davinci.mult, > + clocksource_davinci.shift); > +} > + > +/* > * clockevent > */ > static int davinci_set_next_event(unsigned long cycles, > @@ -377,6 +398,7 @@ static void __init davinci_timer_init(void) > davinci_clock_tick_rate = clk_get_rate(timer_clk); > > /* setup clocksource */ > + clocksource_davinci.read = read_cycles; > clocksource_davinci.name = id_to_name[clocksource_id]; > clocksource_davinci.mult = > clocksource_khz2mult(davinci_clock_tick_rate/1000, From khilman at deeprootsystems.com Thu Oct 7 12:20:23 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 07 Oct 2010 10:20:23 -0700 Subject: [PATCH v4] i2c: davinci: Fix race when setting up for TX In-Reply-To: <87wrpu9bsu.fsf@deeprootsystems.com> (Kevin Hilman's message of "Thu, 07 Oct 2010 10:01:53 -0700") References: <70E876B0EA86DD4BAF101844BC814DFE093EE3EA57@Cloud.RL.local> <87wrpu9bsu.fsf@deeprootsystems.com> Message-ID: <87hbgxapig.fsf@deeprootsystems.com> Kevin Hilman writes: > Jon Povey writes: > >> Hi Ben, >> >> I am not on the i2c list but noticed this pull request: >> http://www.spinics.net/linux/lists/linux-i2c/msg04022.html >> >> I think you have the wrong (old) version of this patch in that branch, >> http://git.fluff.org/gitweb?p=bjdooks/linux.git;a=commitdiff;h=4bba0fd8d1c6d405df666e2573e1a1f917098be0 >> >> The correct v4 one from the start of this thread has more lines >> of patch and this commit message: > > It is also available in my davinci-i2c branch: > git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git davinci-i2c > > Thanks Jon for catching this, I just noticed that it has already been pulled and is part of -rc7. Jon, care to submit a new patch with v4 diff and including the acks and tested-bys? Thanks, Kevin From nsekhar at ti.com Thu Oct 7 23:54:48 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Fri, 8 Oct 2010 10:24:48 +0530 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: <4CADE1B8.50800@mvista.com> References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> <4CADE1B8.50800@mvista.com> Message-ID: Hi Sergei, On Thu, Oct 07, 2010 at 20:35:28, Sergei Shtylyov wrote: > > +static void da830_evm_nor_done(void *data) > > +{ > > + clk_disable(da830_evm_nor.clk); > > + clk_put(da830_evm_nor.clk); > > + iounmap(da830_evm_nor.latch.addr); > > + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > > + iounmap(da830_evm_nor.aemif.addr); > > + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); > > +} > > Why you've changed this function which was useful also for the error cleanup > before? The issues down below aside, I think goto based error handling is clearer to follow. Any objections to using goto based error handing per-se? Thanks, Sekhar > > > +static int da830_evm_nor_init(void *data, int cs) > > +{ > > + /* Turn on AEMIF clocks */ > > + da830_evm_nor.clk = clk_get(NULL, "aemif"); > > + if (IS_ERR(da830_evm_nor.clk)) { > > + pr_err("%s: could not get AEMIF clock\n", __func__); > > + da830_evm_nor.clk = NULL; > > + return -ENODEV; > > + } > > + clk_enable(da830_evm_nor.clk); > > + > > + da830_evm_nor.aemif.res = request_mem_region(DA8XX_AEMIF_CTL_BASE, > > + SZ_32K, "AEMIF control"); > > + if (da830_evm_nor.aemif.res == NULL) { > > + pr_err("%s: could not request AEMIF control region\n", > > + __func__); > > + goto err_aemif_region; > > I wonder why you used goto's at all. Anyway, the error cleanup code is > completely broken now. > > > + } > > + > > + da830_evm_nor.aemif.addr = ioremap_nocache(DA8XX_AEMIF_CTL_BASE, > > + SZ_32K); > > + if (da830_evm_nor.aemif.addr == NULL) { > > + pr_err("%s: could not remap AEMIF control region\n", __func__); > > + goto err_aemif_ioremap; > > + } > > + > > + /* Setup AEMIF -- timings, etc. */ > > + > > + /* Set maximum wait cycles */ > > + davinci_aemif_setup_timing(&da830_evm_norflash_timing, > > + da830_evm_nor.aemif.addr, cs); > > + > > + davinci_aemif_setup_timing(&da830_evm_norflash_timing, > > + da830_evm_nor.aemif.addr, cs + 1); > > + > > + /* Setup the window to access the latch */ > > + da830_evm_nor.latch.res = > > + request_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE, > > + "DA830 UI NOR address latch"); > > + if (da830_evm_nor.latch.res == NULL) { > > + pr_err("%s: could not request address latch region\n", > > + __func__); > > + goto err_latch_region; > > + } > > + > > + da830_evm_nor.latch.addr = > > + ioremap_nocache(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > > + if (da830_evm_nor.latch.addr == NULL) { > > + pr_err("%s: could not remap address latch region\n", __func__); > > + goto err_latch_ioremap; > > + } > > + return 0; > > + > > +err_aemif_region: > > + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); > > Why release what you've just failed to request?! > > > + da830_evm_nor.aemif.res = NULL; > > Useless assignment. > > > + return -EBUSY; > > And you're not calling clk_disable(). > > > +err_aemif_ioremap: > > + iounmap(da830_evm_nor.aemif.addr); > > Why unmap what you've just failed to map?! da830_evm_nor.aemif.addr is NULL. > > > + da830_evm_nor.aemif.addr = NULL; > > Useless assignment. > > > + return -ENOMEM; > > You're not calling release_mem_region() and clk_disable(). > > > +err_latch_region: > > + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > > Why release what you've just failed to request?! > > > + da830_evm_nor.latch.res = NULL; > > Useless assginment. > > > + return -EBUSY; > > You're not calling iounmap() and release_mem_region() for the NOR flash > region and also not calling clk_disable(). > > > + > > +err_latch_ioremap: > > + iounmap(da830_evm_nor.latch.addr); > > Why unmap what you've just failed to map?! da830_evm_nor.latch.addr is NULL. > > > + da830_evm_nor.latch.addr = NULL; > > Useless assginment. > > > + return -ENOMEM; > > You're not release_mem_region() for the latch region, not calling iounmap() > and release_mem_region() for the NOR flash region and also not calling > clk_disable(). > > > +} > [...] > > Your changes made me doubt that you actually understood the code well enough > before doing them... > > WBR, Sergei > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > From sureshs at silvanlabs.com Thu Oct 7 23:55:54 2010 From: sureshs at silvanlabs.com (Suresh Somasekharappa) Date: Fri, 8 Oct 2010 10:25:54 +0530 Subject: Error while decoding using ./moduletest.out alg_vidDec In-Reply-To: References: <2A3DCF3DA181AD40BDE86A3150B27B6B035666B85A@dbde02.ent.ti.com> Message-ID: Hi, I have enabled the h264dec in alg_config and it is now identifying the h264dec. I am facing a new problem now. Please find below the error report Test Video: test.264 Resolution: CIF: 720x480 Error without CE_DEBUG = 3 ./moduletest.out alg_vidDec DRV_SyncRst: module = 47, domain = 0, state = 0 DRV_SyncRst: module = 47, domain = 0, state = 3 CLK Hz, ARM Hz = 432000000 DDR Hz = 340000000 VPSS Hz = 340000000 IMCOP Hz = 340000000 [OSA_FILE ] Reading file [/mnt/nand/IMG_Paramset.bin] ... ERROR IMAGE TUNE: Paramset File is not available..... Setting DEFAULT parameter [OSA_FILE ] Reading file [test.264] ... Done. [9869 bytes] DavinciDisplay DavinciDisplay.1: Before finishing with S_FMT: layer.pix_fmt.bytesperline = 736, layer.pix_fmt.width = 720, layer.pix_fmt.height = 480, layer.pix_fmt.sizeimage =529920 ALG: VidDec: OpDavinciDisplay DavinciDisplay.1: pixfmt->width = 720, layer->layer_info.config.line_length= 736 ening display. DavinciDisplay DavinciDisplay.1: Invalid crop values DavinciDisplay DavinciDisplay.1: Error in S_CROP params ERROR (drv_display.c|DRV_displayExpand|518): VIDIOC_S_CROP ioctl ALG: VidDec: Decode in progress!!! Segmentation fault Any Help would would be greatly appreciated. Regards, Suresh S -------------- next part -------------- An HTML attachment was scrubbed... URL: From suhas.jain at mavensystems.com Fri Oct 8 01:26:59 2010 From: suhas.jain at mavensystems.com (Suhas Jain) Date: Fri, 8 Oct 2010 11:56:59 +0530 Subject: Kernel panic in cppi_completion In-Reply-To: <1285968611-26890-41-git-send-email-khilman@deeprootsystems.com> References: <1285968611-26890-1-git-send-email-khilman@deeprootsystems.com> <1285968611-26890-41-git-send-email-khilman@deeprootsystems.com> Message-ID: Hi All, We are getting a kernel panic in cppi_completion routine for musb. We are using Davinci DM365 with PSP3.20. The board has a SMSC USB hub and we have connected USB storage and USB modem on this hub. The observation during kernel panic is: it seems like USB gets stalled and hence either the USB modem / SCSI layer tried to unlink the URBs. During this there is a interrupt from USB controller and it gives kernel panic in cppi_completion routine. Can somebody help me in this regards? Following is the dump for kernel panic; Log 1: Kernel panic from SCSI layer Unable to handle kernel NULL pointer dereference at virtual address 00000008 pgd = c0004000 [00000008] *pgd=00000000 Internal error: Oops: 17 [#1] PREEMPT Modules linked in: dm365mmap irqk edmak cmemk drv csl power_management libertas_sdio libertas CPU: 0 Tainted: G W (2.6.32-rc2-davinci1 #63) PC is at cppi_completion+0xe4/0x304 LR is at cppi_completion+0x90/0x304 pc : [] lr : [] psr: 80000093 sp : c2791df8 ip : c2791df8 fp : c2791e54 r10: c207e400 r9 : 00000000 r8 : c207e478 r7 : c207e454 r6 : 00000000 r5 : c20518d0 r4 : 0000000d r3 : 00000000 r2 : 0000001f r1 : c051d990 r0 : 00000005 Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 0005317f Table: 82b90000 DAC: 00000017 Process scsi_eh_0 (pid: 991, stack limit = 0xc2790270) Stack: (0xc2791df8 to 0xc2792000) 1de0: c2eb4cc0 c2573200 1e00: c2eb4cc0 c20519d8 00000001 0000000d c20518d0 fec64400 c207e400 fec64140 1e20: fffffffc 00000002 c026d54c 0000000d c20518d0 00000002 fec64000 a0000013 1e40: c2790000 c2791f88 c2791e94 c2791e58 c0268eec c026d688 c2791e84 c2791e68 1e60: c003c4e4 c00399f8 c2051800 c205e280 0000000c 00000001 00000000 00000000 1e80: c2790000 c2791f88 c2791ebc c2791e98 c006e2f0 c0268e64 c0039a84 c2790000 1ea0: c04ccb9c 0000000c c205e280 c05096cc c2791ee4 c2791ec0 c00708c8 c006e2b4 1ec0: c2791ee4 0000000c 00000000 c2760a3c 00000002 00000001 c2791efc c2791ee8 1ee0: c002c070 c00707b0 ffffffff fec48000 c2791f64 c2791f00 c002ca6c c002c010 1f00: ffffff8d 00000024 60000093 60000013 c20a26e0 c2760800 c2760a3c c2790000 1f20: 00000001 c2791f90 c2791f88 c2791f64 c2791ec0 c2791f48 c01bc1e4 c025dce4 1f40: 60000013 ffffffff c2791f6c c20a26e0 c2760800 c2791f84 c2791f74 c2791f68 1f60: c02126c0 c025dc28 c2791fc4 c2791f78 c02141ac c02126a4 c2791fc4 c2791f88 1f80: c03a02a4 c0039dc4 c2791f88 c2791f88 c20a26ec c20a26ec c2791fc4 c2791fcc 1fa0: c2029d88 c2760800 c0214068 00000000 00000000 00000000 c2791ff4 c2791fc8 1fc0: c00573ec c0214078 00000000 00000000 c2791fd0 c2791fd0 00000000 00000000 1fe0: 00000000 00000000 00000000 c2791ff8 c00442f0 c0057378 e46fffd5 00000000 Backtrace: [] (cppi_completion+0x0/0x304) from [] (davinci_interrupt+0x98/0x2c0) [] (davinci_interrupt+0x0/0x2c0) from [] (handle_IRQ_event+0x4c/0x118) [] (handle_IRQ_event+0x0/0x118) from [] (handle_edge_irq+0x128/0x1b8) r8:c05096cc r7:c205e280 r6:0000000c r5:c04ccb9c r4:c2790000 [] (handle_edge_irq+0x0/0x1b8) from [] (asm_do_IRQ+0x70/0x8c) r8:00000001 r7:00000002 r6:c2760a3c r5:00000000 r4:0000000c [] (asm_do_IRQ+0x0/0x8c) from [] (__irq_svc+0x4c/0x90) Exception stack(0xc2791f00 to 0xc2791f48) 1f00: ffffff8d 00000024 60000093 60000013 c20a26e0 c2760800 c2760a3c c2790000 1f20: 00000001 c2791f90 c2791f88 c2791f64 c2791ec0 c2791f48 c01bc1e4 c025dce4 1f40: 60000013 ffffffff r5:fec48000 r4:ffffffff [] (command_abort+0x0/0x104) from [] (__scsi_try_to_abort_cmd+0x2c/0x34) r6:c2791f84 r5:c2760800 r4:c20a26e0 [] (__scsi_try_to_abort_cmd+0x0/0x34) from [] (scsi_error_handler+0x144/0x388) [] (scsi_error_handler+0x0/0x388) from [] (kthread+0x84/0x8c) [] (kthread+0x0/0x8c) from [] (do_exit+0x0/0x654) r7:00000000 r6:00000000 r5:00000000 r4:00000000 Code: e88d5000 e58d4008 e58d500c ebf7525f (e1d630b8) Kernel panic - not syncing: Fatal exception in interrupt Backtrace: [] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c) r6:c2791db0 r5:c2790000 r4:c04f5690 [] (dump_stack+0x0/0x1c) from [] (panic+0x54/0x124) [] (panic+0x0/0x124) from [] (die+0x150/0x17c) r3:00010000 r2:c2790000 r1:c04f5690 r0:c0441814 [] (die+0x0/0x17c) from [] (__do_kernel_fault+0x6c/0x7c) [] (__do_kernel_fault+0x0/0x7c) from [] (do_page_fault+0x1cc/0x1e4) r7:00000000 r6:00000008 r5:c2026d80 r4:ffffffff [] (do_page_fault+0x0/0x1e4) from [] (do_DataAbort+0x40/0xa4) [] (do_DataAbort+0x0/0xa4) from [] (__dabt_svc+0x4c/0x60) Exception stack(0xc2791db0 to 0xc2791df8) 1da0: 00000005 c051d990 0000001f 00000000 1dc0: 0000000d c20518d0 00000000 c207e454 c207e478 00000000 c207e400 c2791e54 1de0: c2791df8 c2791df8 c026d708 c026d75c 80000093 ffffffff r8:c207e478 r7:c207e454 r6:00000000 r5:c2791de4 r4:ffffffff [] (cppi_completion+0x0/0x304) from [] (davinci_interrupt+0x98/0x2c0) [] (davinci_interrupt+0x0/0x2c0) from [] (handle_IRQ_event+0x4c/0x118) [] (handle_IRQ_event+0x0/0x118) from [] (handle_edge_irq+0x128/0x1b8) r8:c05096cc r7:c205e280 r6:0000000c r5:c04ccb9c r4:c2790000 [] (handle_edge_irq+0x0/0x1b8) from [] (asm_do_IRQ+0x70/0x8c) r8:00000001 r7:00000002 r6:c2760a3c r5:00000000 r4:0000000c [] (asm_do_IRQ+0x0/0x8c) from [] (__irq_svc+0x4c/0x90) Exception stack(0xc2791f00 to 0xc2791f48) 1f00: ffffff8d 00000024 60000093 60000013 c20a26e0 c2760800 c2760a3c c2790000 1f20: 00000001 c2791f90 c2791f88 c2791f64 c2791ec0 c2791f48 c01bc1e4 c025dce4 1f40: 60000013 ffffffff r5:fec48000 r4:ffffffff [] (command_abort+0x0/0x104) from [] (__scsi_try_to_abort_cmd+0x2c/0x34) r6:c2791f84 r5:c2760800 r4:c20a26e0 [] (__scsi_try_to_abort_cmd+0x0/0x34) from [] (scsi_error_handler+0x144/0x388) [] (scsi_error_handler+0x0/0x388) from [] (kthread+0x84/0x8c) [] (kthread+0x0/0x8c) from [] (do_exit+0x0/0x654) r7:00000000 r6:00000000 r5:00000000 r4:00000000 Log 2: Kernel panic from usb-serial (USB modem) Unable to handle kernel NULL pointer dereference at virtual address 00000008 pgd = c3854000 [00000008] *pgd=81fbd031, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] PREEMPT Modules linked in: dm365mmap irqk edmak cmemk drv csl power_management libertas_sdio libertas CPU: 0 Not tainted (2.6.32-rc2-davinci1 #90) PC is at cppi_completion+0xcc/0x2ec LR is at cppi_completion+0x78/0x2ec pc : [] lr : [] psr: 80000093 sp : c0775c58 ip : c0775c58 fp : c0775cb4 r10: c2076400 r9 : 00000000 r8 : c2076478 r7 : c2076454 r6 : 00000000 r5 : c20558d0 r4 : 00000001 r3 : 00000000 r2 : 00000e08 r1 : c0549640 r0 : 00000005 Flags: Nzcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user Control: 0005317f Table: 83854000 DAC: 00000015 Process avl_qt (pid: 2532, stack limit = 0xc0774270) Stack: (0xc0775c58 to 0xc0776000) 5c40: c0775c74 c0775c68 5c60: c0054414 00000001 00000001 00000001 c20558d0 fec64400 c2076400 fec64140 5c80: fffffffc 00000002 c0054a40 00000001 c20558d0 00000002 fec64000 60000013 5ca0: c0774000 00000000 c0775cf4 c0775cb8 c026e4cc c0272d24 c0253f94 c01c24b0 5cc0: c0775ce4 c0775cd0 c0252268 c2075c40 0000000c 00000001 00000000 00000000 5ce0: c0774000 00000000 c0775d1c c0775cf8 c006f434 c026e464 c0775d34 c0774000 5d00: c04f6b98 0000000c c2075c40 c05353b0 c0775d44 c0775d20 c0071a0c c006f3f8 5d20: c0775d44 0000000c 00000000 c2e03500 00000002 00000001 c0775d5c c0775d48 5d40: c002d070 c00718f4 ffffffff fec48000 c0775dec c0775d60 c002da6c c002d010 5d60: 00000000 000000c0 c04ee3f8 c06b9380 c2055800 c06b9000 c2e03500 ffffff98 5d80: 80000013 00000000 00000000 c0775dec 00000000 c0775da8 c0098ed8 c02719f8 5da0: 20000013 ffffffff 00000000 00000000 c0774000 00000011 c0775dec c20558d0 5dc0: c006f434 c2055800 c2e03500 c2e03500 ffffff98 ffffff98 c0774000 00000008 5de0: c0775e14 c0775df0 c0252374 c02718a0 c0775e14 a0000013 00000000 c2e03500 5e00: ffffff98 00000000 c0775e34 c0775e18 c0252d38 c0252280 c2e96540 c2e03500 5e20: 00000008 c0610800 c0775e44 c0775e38 c0253b10 c0252cc4 c0775e94 c0775e48 5e40: c0268bd4 c0253ae0 c0775e84 c0775e58 c2e96588 c2e96580 00000008 c0610800 5e60: c2e96540 c2b32d60 c03bf480 c2c56400 c320c800 00000008 c0610800 c0774000 5e80: c2e03d80 c320cbc8 c0775ebc c0775e98 c0264c68 c0268b20 c0058a04 c003af04 5ea0: c2ebfa80 c320c800 c0610800 00000008 c0775f0c c0775ec0 c01e2ff8 c0264be0 5ec0: c2e03d80 c0610800 c0775f0c 00000000 c2ebfa80 c003e184 c320c910 c320c910 5ee0: c320cbb0 00000008 00000008 c320c800 c0774000 000815c0 c2e03d80 00000008 5f00: c0775f54 c0775f10 c01e0260 c01e2d50 c01e61ec c01e2d40 c2d5c440 00000000 5f20: 4b4b9dc1 3b39906d c009e3f0 c2e03d80 000815c0 c0775f78 00000004 c002dfe4 5f40: c0774000 00000000 c0775f74 c0775f58 c009d93c c01e00e4 c00602e8 00000000 5f60: 00000000 c2e03d80 c0775fa4 c0775f78 c009de20 c009d898 00000000 00000000 5f80: 4b4b9dc2 00000001 425008d0 00000015 00061eb8 40ce1550 00000000 c0775fa8 5fa0: c002de60 c009ddec 00000015 00061eb8 00000015 000815c0 00000008 34393000 5fc0: 00000015 00061eb8 40ce1550 00000004 003d0f00 beef6b74 00000000 beef6b74 5fe0: 00000000 41bdedc8 40ce94dc 40ce9bc4 80000010 00000015 00000000 00000000 Backtrace: [] (cppi_completion+0x0/0x2ec) from [] (davinci_interrupt+0x78/0x29c) [] (davinci_interrupt+0x0/0x29c) from [] (handle_IRQ_event+0x4c/0x118) [] (handle_IRQ_event+0x0/0x118) from [] (handle_edge_irq+0x128/0x1b8) r8:c05353b0 r7:c2075c40 r6:0000000c r5:c04f6b98 r4:c0774000 [] (handle_edge_irq+0x0/0x1b8) from [] (asm_do_IRQ+0x70/0x8c) r8:00000001 r7:00000002 r6:c2e03500 r5:00000000 r4:0000000c [] (asm_do_IRQ+0x0/0x8c) from [] (__irq_svc+0x4c/0x90) Exception stack(0xc0775d60 to 0xc0775da8) 5d60: 00000000 000000c0 c04ee3f8 c06b9380 c2055800 c06b9000 c2e03500 ffffff98 5d80: 80000013 00000000 00000000 c0775dec 00000000 c0775da8 c0098ed8 c02719f8 5da0: 20000013 ffffffff r5:fec48000 r4:ffffffff [] (musb_urb_dequeue+0x0/0x1b4) from [] (unlink1+0x104/0x110) [] (unlink1+0x0/0x110) from [] (usb_hcd_unlink_urb+0x84/0xa0) r8:00000000 r7:ffffff98 r6:c2e03500 r5:00000000 r4:a0000013 [] (usb_hcd_unlink_urb+0x0/0xa0) from [] (usb_unlink_urb+0x40/0x44) r7:c0610800 r6:00000008 r5:c2e03500 r4:c2e96540 [] (usb_unlink_urb+0x0/0x44) from [] (option_write+0xc4/0x2bc) [] (option_write+0x0/0x2bc) from [] (serial_write+0x98/0xb0) [] (serial_write+0x0/0xb0) from [] (n_tty_write+0x2b8/0x3a4) r7:00000008 r6:c0610800 r5:c320c800 r4:c2ebfa80 [] (n_tty_write+0x0/0x3a4) from [] (tty_write+0x18c/0x234) [] (tty_write+0x0/0x234) from [] (vfs_write+0xb4/0xdc) [] (vfs_write+0x0/0xdc) from [] (sys_write+0x44/0x70) r6:c2e03d80 r5:00000000 r4:00000000 [] (sys_write+0x0/0x70) from [] (ret_fast_syscall+0x0/0x28) r6:40ce1550 r5:00061eb8 r4:00000015 Code: e88d5000 e58d4008 e58d500c ebf7410e (e1d630b8) INTERFACE [ppp0]Kernel panic - not syncing: Fatal exception in interrupt GSM : CMD [+CBacktrace: SQ] GSM : GSM CMD[AT+CSQ [] (dump_backtrace+0x0/0x110) from [] (dump_stack+0x18/0x1c) r6:c0775c10 r5:c0774000 r4:c0521370 [] (dump_stack+0x0/0x1c) from [] (panic+0x54/0x124) [] (panic+0x0/0x124) from [] (die+0x150/0x17c) r3:00010000 r2:c0774000 r1:c0521370 r0:c0463704 [] (die+0x0/0x17c) from [] (__do_kernel_fault+0x6c/0x7c) [] (__do_kernel_fault+0x0/0x7c) from [] (do_page_fault+0x1cc/0x1e4) r7:c002b600 r6:00000008 r5:c2ebfa80 r4:ffffffff [] (do_page_fault+0x0/0x1e4) from [] (do_DataAbort+0x40/0xa4) [] (do_DataAbort+0x0/0xa4) from [] (__dabt_svc+0x4c/0x60) Exception stack(0xc0775c10 to 0xc0775c58) 5c00: 00000005 c0549640 00000e08 00000000 5c20: 00000001 c20558d0 00000000 c2076454 c2076478 00000000 c2076400 c0775cb4 5c40: c0775c58 c0775c58 c0272d8c c0272de0 80000093 ffffffff r8:c2076478 r7:c2076454 r6:00000000 r5:c0775c44 r4:ffffffff [] (cppi_completion+0x0/0x2ec) from [] (davinci_interrupt+0x78/0x29c) [] (davinci_interrupt+0x0/0x29c) from [] (handle_IRQ_event+0x4c/0x118) [] (handle_IRQ_event+0x0/0x118) from [] (handle_edge_irq+0x128/0x1b8) r8:c05353b0 r7:c2075c40 r6:0000000c r5:c04f6b98 r4:c0774000 [] (handle_edge_irq+0x0/0x1b8) from [] (asm_do_IRQ+0x70/0x8c) r8:00000001 r7:00000002 r6:c2e03500 r5:00000000 r4:0000000c [] (asm_do_IRQ+0x0/0x8c) from [] (__irq_svc+0x4c/0x90) Exception stack(0xc0775d60 to 0xc0775da8) 5d60: 00000000 000000c0 c04ee3f8 c06b9380 c2055800 c06b9000 c2e03500 ffffff98 5d80: 80000013 00000000 00000000 c0775dec 00000000 c0775da8 c0098ed8 c02719f8 5da0: 20000013 ffffffff r5:fec48000 r4:ffffffff [] (musb_urb_dequeue+0x0/0x1b4) from [] (unlink1+0x104/0x110) [] (unlink1+0x0/0x110) from [] (usb_hcd_unlink_urb+0x84/0xa0) r8:00000000 r7:ffffff98 r6:c2e03500 r5:00000000 r4:a0000013 [] (usb_hcd_unlink_urb+0x0/0xa0) from [] (usb_unlink_urb+0x40/0x44) r7:c0610800 r6:00000008 r5:c2e03500 r4:c2e96540 [] (usb_unlink_urb+0x0/0x44) from [] (option_write+0xc4/0x2bc) [] (option_write+0x0/0x2bc) from [] (serial_write+0x98/0xb0) [] (serial_write+0x0/0xb0) from [] (n_tty_write+0x2b8/0x3a4) r7:00000008 r6:c0610800 r5:c320c800 r4:c2ebfa80 [] (n_tty_write+0x0/0x3a4) from [] (tty_write+0x18c/0x234) [] (tty_write+0x0/0x234) from [] (vfs_write+0xb4/0xdc) [] (vfs_write+0x0/0xdc) from [] (sys_write+0x44/0x70) r6:c2e03d80 r5:00000000 r4:00000000 [] (sys_write+0x0/0x70) from [] (ret_fast_syscall+0x0/0x28) r6:40ce1550 r5:00061eb8 r4:00000015 From nsekhar at ti.com Fri Oct 8 01:50:15 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Fri, 8 Oct 2010 12:20:15 +0530 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> <4CADE1B8.50800@mvista.com> Message-ID: On Fri, Oct 08, 2010 at 12:14:33, Vitaly Wool wrote: > On Fri, Oct 8, 2010 at 5:54 AM, Nori, Sekhar wrote: > > Hi Sergei, > > > > On Thu, Oct 07, 2010 at 20:35:28, Sergei Shtylyov wrote: > > > >> > +static void da830_evm_nor_done(void *data) > >> > +{ > >> > + clk_disable(da830_evm_nor.clk); > >> > + clk_put(da830_evm_nor.clk); > >> > + iounmap(da830_evm_nor.latch.addr); > >> > + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); > >> > + iounmap(da830_evm_nor.aemif.addr); > >> > + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); > >> > +} > >> > >> Why you've changed this function which was useful also for the error cleanup > >> before? > > > > The issues down below aside, I think goto based error handling > > is clearer to follow. Any objections to using goto based > > error handing per-se? > > What you're saying just doesn't make sense in this context. Whatever > way of error handling is chosen, it first needs to be correct which is > absolutely not the case here. Yes, agreed. It needs to be correct first. Thanks, Sekhar From sshtylyov at mvista.com Fri Oct 8 04:52:26 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 08 Oct 2010 13:52:26 +0400 Subject: [PATCH] davinci: Implement sched_clock() In-Reply-To: <87pqvm9bbv.fsf@deeprootsystems.com> References: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> <87pqvm9bbv.fsf@deeprootsystems.com> Message-ID: <4CAEE9DA.1020900@mvista.com> Hello. On 07-10-2010 21:12, Kevin Hilman wrote: >> Overwrite the default implementation of sched_clock that is based on >> jiffies by something more precise. This improves timestamps in ftrace. >> Implementation is copied from OMAP platform code. >> Signed-off-by: Andreas Gaeer > Thanks, applying to davinci git. > Will queue for 2.6.38 (it's a bit too late for 2.6.37 as Linus only > wants real regression fixes after -rc6.) Did you mean 2.6.37 and 2.6.36 respecitvely? WBR, Sergei From sshtylyov at mvista.com Fri Oct 8 04:56:47 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 08 Oct 2010 13:56:47 +0400 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> <4CADE1B8.50800@mvista.com> Message-ID: <4CAEEADF.5070103@mvista.com> Hello. On 08-10-2010 8:54, Nori, Sekhar wrote: >>> +static void da830_evm_nor_done(void *data) >>> +{ >>> + clk_disable(da830_evm_nor.clk); >>> + clk_put(da830_evm_nor.clk); >>> + iounmap(da830_evm_nor.latch.addr); >>> + release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); >>> + iounmap(da830_evm_nor.aemif.addr); >>> + release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); >>> +} >> Why you've changed this function which was useful also for the error cleanup >> before? > The issues down below aside, I think goto based error handling > is clearer to follow. Any objections to using goto based > error handing per-se? I think the code was more compact with the old error handling. And anyway, I'm not feeling happy when TI is changing MV's code. > Thanks, > Sekhar WBR, Sergei From nsekhar at ti.com Fri Oct 8 05:14:28 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Fri, 8 Oct 2010 15:44:28 +0530 Subject: [PATCH v1] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1286223843-20913-1-git-send-email-vm.rod25@gmail.com> <4CAAF099.8040800@mvista.com> Message-ID: Hi Victor, On Tue, Oct 05, 2010 at 22:42:40, Victor Rodriguez wrote: > On Tue, Oct 5, 2010 at 4:32 AM, Sergei Shtylyov wrote: > > Hello. > > > > On 05-10-2010 0:24, vm.rod25 at gmail.com wrote: > > > >> From: Victor Rodriguez > > > >> This patch adds EMAC support for the Hawkboard-L138 system > >> It is under the machine name "omapl138_hawkboard". > >> This system is based on the da850 davinci CPU architecture. > > > >> Signed-off-by: Victor Rodriguez > >> --- > >> arch/arm/mach-davinci/board-omapl138-hawk.c | 49 > >> +++++++++++++++++++++++++++ > >> 1 files changed, 49 insertions(+), 0 deletions(-) > >> > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > >> b/arch/arm/mach-davinci/board-omapl138-hawk.c > >> index c472dd8..b22c275 100644 > >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > >> @@ -19,6 +19,55 @@ > > > > [...] > > > >> +static int __init omapl138_hawk_config_emac(void) > >> +{ > >> + void __iomem *cfg_chip3_base; > > > > Why not just 'cfgchip3'? > > Because the board file arch/arm/mach-davinci/board-da850-evm.c has the > same name I would like to have coherence because we said taht it is > based on da850 architecture. I am not sure it really breaks any coherence. Short local variable names are easier to read. CFGCHIP3 is a single register, so _base is redundant anyway. Thanks, Sekhar From sugumar at ti.com Fri Oct 8 08:16:42 2010 From: sugumar at ti.com (sugumar) Date: Fri, 8 Oct 2010 18:46:42 +0530 Subject: [PATCH 0/4] Add eCAP driver support for PWM based backlight control. Message-ID: <1286543802-32023-1-git-send-email-sugumar@ti.com> The following set of patches adds support for eCAP driver for PWM generation. It also adds platform support for back light device. The patch as a whole adds support for back light control through eCAP module. The patch has been tested on Bill Gatliff's tree. sugumar (4): davinci: da8xx: eCAP driver for PWM signal generation davinci: da850: Add platform specific support for eCAP driver Modify the back light driver to support the new PWM framework davinci: da850/omap-l138 evm: Platform support for backlight driver arch/arm/mach-davinci/board-da850-evm.c | 37 +++ arch/arm/mach-davinci/da850.c | 69 ++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 1 + arch/arm/mach-davinci/include/mach/mux.h | 3 + drivers/pwm/Kconfig | 11 + drivers/pwm/Makefile | 1 + drivers/pwm/ecap.c | 330 ++++++++++++++++++++++++++++ drivers/video/backlight/pwm_bl.c | 28 ++- include/linux/pwm_backlight.h | 3 +- 9 files changed, 469 insertions(+), 14 deletions(-) create mode 100644 drivers/pwm/ecap.c From sugumar at ti.com Fri Oct 8 08:17:06 2010 From: sugumar at ti.com (sugumar) Date: Fri, 8 Oct 2010 18:47:06 +0530 Subject: [PATCH 1/4] davinci: da8xx: eCAP driver for PWM signal generation Message-ID: <1286543826-32050-1-git-send-email-sugumar@ti.com> OMAPL138/DA850 contains three instances of eCAP module. Each eCAP module has one dedicated pin that can be used either in capture mode(input) or in PWM mode. For more information on eCAP module operation, please refer to the following url. http://focus.ti.com/lit/ug/sprufl2a/sprufl2a.pdf This patch adds eCAP driver support for PWM signal generation. Signed-off-by: sugumar --- drivers/pwm/Kconfig | 10 ++ drivers/pwm/Makefile | 1 + drivers/pwm/ecap.c | 330 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 341 insertions(+), 0 deletions(-) create mode 100644 drivers/pwm/ecap.c diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index def003b..6f32dd6 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -33,4 +33,14 @@ config GPIO_PWM This option enables a single-channel PWM device using a kernel interval timer and a GPIO pin. If unsure, say N. +config ECAP_PWM + tristate "eCAP PWM support" + depends on ARCH_DAVINCI_DA8XX + help + This option enables device driver support for eCAP module found + on DA8xx Processors. eCAP module is used to geenrate wide range + of PWM waveforms. Maximum frequency generated is equal to half + the system clock frequency. + Say Y to enable the eCAP support. If you want to build it as a + module, Say M. endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 03ae2cd..6f02c9b 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_GENERIC_PWM) += pwm.o obj-$(CONFIG_ATMEL_PWM) += atmel-pwm.o obj-$(CONFIG_PXA_PWM) += pxa-pwm.o obj-$(CONFIG_GPIO_PWM) += gpio.o +obj-$(CONFIG_ECAP_PWM) += ecap.o diff --git a/drivers/pwm/ecap.c b/drivers/pwm/ecap.c new file mode 100644 index 0000000..763586e --- /dev/null +++ b/drivers/pwm/ecap.c @@ -0,0 +1,330 @@ +/* + * eCAP driver for PWM output generation + * + * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed .as is. WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMER_CTR_REG 0x0 +#define CAPTURE_2_REG 0x0c +#define CAPTURE_3_REG 0x10 +#define CAPTURE_4_REG 0x14 +#define CAPTURE_CTRL2_REG 0x2A + +#define ECTRL2_SYNCOSEL_MASK (0x03 << 6) + +#define ECTRL2_MDSL_ECAP BIT(9) +#define ECTRL2_CTRSTP_FREERUN BIT(4) +#define ECTRL2_PLSL_LOW BIT(10) +#define ECTRL2_SYNC_EN BIT(5) + +struct ecap_pwm { + struct pwm_device pwm; + spinlock_t lock; + struct clk *clk; + int clk_enabled; + void __iomem *mmio_base; +}; + +static inline struct ecap_pwm *to_ecap_pwm(const struct pwm_channel *p) +{ + return container_of(p->pwm, struct ecap_pwm, pwm); +} + +static int ecap_pwm_stop(struct pwm_channel *p) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) & + ~BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + if (ep->clk_enabled) { + clk_disable(ep->clk); + ep->clk_enabled = 0; + } + + return 0; +} + +static int ecap_pwm_start(struct pwm_channel *p) +{ + int ret = 0; + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) | + BIT(4), ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + if (!ep->clk_enabled) { + ret = clk_enable(ep->clk); + if (ret) + return ret; + ep->clk_enabled = 1; + } + + return ret; +} + +static int ecap_pwm_set_polarity(struct pwm_channel *p, char pol) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) & + (~BIT(10) | pol), ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + return 0; +} + +static int ecap_pwm_unsynchronize(struct pwm_channel *p) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) & + (~ECTRL2_SYNCOSEL_MASK | 0x2 << 6) & ~ECTRL2_SYNC_EN, + ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + return 0; +} + +static int ecap_pwm_synchronize(struct pwm_channel *p) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(__raw_readw(ep->mmio_base + CAPTURE_CTRL2_REG) & + ((~ECTRL2_SYNCOSEL_MASK) | ECTRL2_SYNC_EN), + ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + return 0; +} + +static int ecap_pwm_config_period(struct pwm_channel *p) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writel((p->period_ticks) - 1, ep->mmio_base + CAPTURE_3_REG); + __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | + ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG); + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + return 0; +} + + +static int ecap_pwm_config_duty(struct pwm_channel *p) +{ + unsigned long flags; + struct ecap_pwm *ep = to_ecap_pwm(p); + + clk_enable(ep->clk); + + spin_lock_irqsave(&p->lock, flags); + __raw_writew(ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | + ECTRL2_CTRSTP_FREERUN, ep->mmio_base + CAPTURE_CTRL2_REG); + if (p->duty_ticks > 0) { + __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_4_REG); + } else { + __raw_writel(p->duty_ticks, ep->mmio_base + CAPTURE_2_REG); + __raw_writel(0, ep->mmio_base + TIMER_CTR_REG); + } + spin_unlock_irqrestore(&p->lock, flags); + + clk_disable(ep->clk); + return 0; +} + +static int ecap_pwm_config(struct pwm_channel *p, + struct pwm_channel_config *c) +{ + int ret = 0; + switch (c->config_mask) { + + case PWM_CONFIG_DUTY_TICKS: + p->duty_ticks = c->duty_ticks; + ret = ecap_pwm_config_duty(p); + break; + + case PWM_CONFIG_PERIOD_TICKS: + p->period_ticks = c->period_ticks; + ret = ecap_pwm_config_period(p); + break; + + case PWM_CONFIG_POLARITY: + ret = ecap_pwm_set_polarity(p, c->polarity); + break; + + case PWM_CONFIG_START: + ret = ecap_pwm_start(p); + break; + + case PWM_CONFIG_STOP: + ret = ecap_pwm_stop(p); + break; + } + + return ret; +} + +static int ecap_pwm_request(struct pwm_channel *p) +{ + struct ecap_pwm *ep = to_ecap_pwm(p); + + p->tick_hz = clk_get_rate(ep->clk); + return 0; +} + +static int __init ecap_probe(struct platform_device *pdev) +{ + struct ecap_pwm *ep = NULL; + struct resource *r; + int ret = 0; + + ep = kzalloc(sizeof(*ep), GFP_KERNEL); + if (!ep) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + ret = -ENOMEM; + goto err_ecap_pwm_alloc; + } + + ep->clk = clk_get(&pdev->dev, "ecap"); + if (IS_ERR(ep->clk)) { + ret = PTR_ERR(ep->clk); + goto err_free; + } + + spin_lock_init(&ep->lock); + ep->pwm.dev = &pdev->dev; + ep->pwm.bus_id = dev_name(&pdev->dev); + ep->pwm.owner = THIS_MODULE; + ep->pwm.config = ecap_pwm_config; + ep->pwm.request = ecap_pwm_request; + ep->pwm.nchan = 1; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!r) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, resource_size(r), pdev->name); + if (!r) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + ep->mmio_base = ioremap(r->start, resource_size(r)); + if (!ep->mmio_base) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + ret = pwm_register(&ep->pwm); + platform_set_drvdata(pdev, ep); + return 0; + +err_free_mem: + release_mem_region(r->start, resource_size(r)); +err_free_clk: + clk_put(ep->clk); +err_free: + kfree(ep); +err_ecap_pwm_alloc: + return ret; +} + +static int __devexit ecap_remove(struct platform_device *pdev) +{ + struct ecap_pwm *ep = platform_get_drvdata(pdev); + struct resource *r; + + ep = platform_get_drvdata(pdev); + if (!ep) + return -ENODEV; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, resource_size(r)); + platform_set_drvdata(pdev, NULL); + pwm_unregister(&ep->pwm); + iounmap(ep->mmio_base); + clk_put(ep->clk); + kfree(ep); + + return 0; +} + +static struct platform_driver ecap_driver = { + .driver = { + .name = "ecap", + .owner = THIS_MODULE, + }, + .probe = ecap_probe, + .remove = __devexit_p(ecap_remove), +}; + +static int __init ecap_init(void) +{ + return platform_driver_register(&ecap_driver); +} + +static void __exit ecap_exit(void) +{ + platform_driver_unregister(&ecap_driver); +} + +module_init(ecap_init); +module_exit(ecap_exit); + +MODULE_AUTHOR("sugumar "); +MODULE_ALIAS("platform:ecap"); +MODULE_LICENSE("GPL v2"); -- 1.5.6 From sugumar at ti.com Fri Oct 8 08:17:23 2010 From: sugumar at ti.com (sugumar) Date: Fri, 8 Oct 2010 18:47:23 +0530 Subject: [PATCH 2/4] davinci: da850: Add platform specific support for eCAP driver Message-ID: <1286543843-32088-1-git-send-email-sugumar@ti.com> This patch registers the eCAP driver as a platform device Signed-off-by: sugumar --- arch/arm/mach-davinci/da850.c | 69 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/da8xx.h | 1 + arch/arm/mach-davinci/include/mach/mux.h | 3 + 3 files changed, 73 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 6b8331b..2adfb08 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -336,6 +336,13 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk ecap_clk = { + .name = "ecap", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_ECAP, + .gpsc = 1, +}; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -377,6 +384,7 @@ static struct clk_lookup da850_clks[] = { CLK("da8xx_lcdc.0", NULL, &lcdc_clk), CLK("davinci_mmc.0", NULL, &mmcsd_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "ecap", &ecap_clk), CLK(NULL, NULL, NULL), }; @@ -539,6 +547,9 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) + MUX_CFG(DA850, ECAP0_APWM0, 2, 28, 15, 2, false) + MUX_CFG(DA850, ECAP1_APWM1, 1, 28, 15, 4, false) + MUX_CFG(DA850, ECAP2_APWM2, 1, 0, 15, 4, false) #endif }; @@ -1029,6 +1040,64 @@ static int da850_round_armrate(struct clk *clk, unsigned long rate) } #endif + +#define DA8XX_ECAP0_BASE 0x01F06000 + +static struct resource da850_ecap0_resource[] = { + { + .start = DA8XX_ECAP0_BASE, + .end = DA8XX_ECAP0_BASE + 0xfff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da850_ecap0_dev = { + .name = "ecap", + .id = 0, + .resource = da850_ecap0_resource, + .num_resources = ARRAY_SIZE(da850_ecap0_resource), +}; + +#define DA8XX_ECAP1_BASE 0x01F07000 + +static struct resource da850_ecap1_resource[] = { + { + .start = DA8XX_ECAP1_BASE, + .end = DA8XX_ECAP1_BASE + 0xfff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da850_ecap1_dev = { + .name = "ecap", + .id = 1, + .resource = da850_ecap1_resource, + .num_resources = ARRAY_SIZE(da850_ecap1_resource), +}; + +#define DA8XX_ECAP2_BASE 0x01F08000 + +static struct resource da850_ecap2_resource[] = { + { + .start = DA8XX_ECAP2_BASE, + .end = DA8XX_ECAP2_BASE + 0xfff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device da850_ecap2_dev = { + .name = "ecap", + .id = 2, + .resource = da850_ecap2_resource, + .num_resources = ARRAY_SIZE(da850_ecap2_resource), +}; + +int __init da850_register_ecap(void) +{ + return platform_device_register(&da850_ecap2_dev); +} + + int da850_register_pm(struct platform_device *pdev) { int ret; diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 1b31a9a..63e36d5 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -81,6 +81,7 @@ int da850_register_cpufreq(void); int da8xx_register_cpuidle(void); void __iomem * __init da8xx_get_mem_ctlr(void); int da850_register_pm(struct platform_device *pdev); +int da850_register_ecap(void); extern struct platform_device da8xx_serial_device; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..c82cb49 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -914,6 +914,9 @@ enum davinci_da850_index { DA850_GPIO4_0, DA850_GPIO4_1, DA850_RTC_ALARM, + DA850_ECAP0_APWM0, + DA850_ECAP1_APWM1, + DA850_ECAP2_APWM2, }; enum davinci_tnetv107x_index { -- 1.5.6 From sugumar at ti.com Fri Oct 8 08:17:43 2010 From: sugumar at ti.com (sugumar) Date: Fri, 8 Oct 2010 18:47:43 +0530 Subject: [PATCH 3/4] Modify the back light driver to support the new PWM framework Message-ID: <1286543863-32115-1-git-send-email-sugumar@ti.com> This patch makes necessary changes to the existing backlight driver to work with the new PWM framework Signed-off-by: sugumar --- drivers/pwm/Kconfig | 1 + drivers/video/backlight/pwm_bl.c | 28 +++++++++++++++------------- include/linux/pwm_backlight.h | 3 ++- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 6f32dd6..0c90d98 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -5,6 +5,7 @@ menuconfig GENERIC_PWM tristate "PWM Support" depends on SYSFS + select HAVE_PWM help This enables PWM support through the generic PWM API. If unsure, say N. diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 5504435..591a2fd 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -17,12 +17,12 @@ #include #include #include -#include +#include #include #include struct pwm_bl_data { - struct pwm_device *pwm; + struct pwm_channel *pwm; struct device *dev; unsigned int period; int (*notify)(struct device *, @@ -45,11 +45,13 @@ static int pwm_backlight_update_status(struct backlight_device *bl) brightness = pb->notify(pb->dev, brightness); if (brightness == 0) { - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_set_period_ns(pb->pwm, pb->period); + pwm_set_duty_ns(pb->pwm, 0); + pwm_stop(pb->pwm); } else { - pwm_config(pb->pwm, brightness * pb->period / max, pb->period); - pwm_enable(pb->pwm); + pwm_set_period_ns(pb->pwm, pb->period); + pwm_set_duty_ns(pb->pwm, brightness * pb->period / max); + pwm_start(pb->pwm); } return 0; } @@ -94,7 +96,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) pb->notify = data->notify; pb->dev = &pdev->dev; - pb->pwm = pwm_request(data->pwm_id, "backlight"); + pb->pwm = pwm_request(data->pwm_id, data->ch, "backlight"); if (IS_ERR(pb->pwm)) { dev_err(&pdev->dev, "unable to request PWM for backlight\n"); ret = PTR_ERR(pb->pwm); @@ -119,7 +121,7 @@ static int pwm_backlight_probe(struct platform_device *pdev) return 0; err_bl: - pwm_free(pb->pwm); + pwm_release(pb->pwm); err_pwm: kfree(pb); err_alloc: @@ -135,9 +137,9 @@ static int pwm_backlight_remove(struct platform_device *pdev) struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); backlight_device_unregister(bl); - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); - pwm_free(pb->pwm); + pwm_set_duty_ns(pb->pwm, 0); + pwm_stop(pb->pwm); + pwm_release(pb->pwm); kfree(pb); if (data->exit) data->exit(&pdev->dev); @@ -153,8 +155,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, if (pb->notify) pb->notify(pb->dev, 0); - pwm_config(pb->pwm, 0, pb->period); - pwm_disable(pb->pwm); + pwm_set_duty_ns(pb->pwm, 0); + pwm_stop(pb->pwm); return 0; } diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h index 01b3d75..eb325bb 100644 --- a/include/linux/pwm_backlight.h +++ b/include/linux/pwm_backlight.h @@ -5,7 +5,8 @@ #define __LINUX_PWM_BACKLIGHT_H struct platform_pwm_backlight_data { - int pwm_id; + const char *pwm_id; + int ch; unsigned int max_brightness; unsigned int dft_brightness; unsigned int pwm_period_ns; -- 1.5.6 From sugumar at ti.com Fri Oct 8 08:18:01 2010 From: sugumar at ti.com (sugumar) Date: Fri, 8 Oct 2010 18:48:01 +0530 Subject: [PATCH 4/4] davinci: da850/omap-l138 evm: Platform support for backlight driver Message-ID: <1286543881-32141-1-git-send-email-sugumar@ti.com> on DA850/OMAP-L138 EVM, eCAP module is used to control the LCD backlight. This patch registers the backlight device as platform device, confgiures the pins for PWM output and also sets the backlight specific data such as period, maximum intensity and default brightness. Signed-off-by: sugumar --- arch/arm/mach-davinci/board-da850-evm.c | 37 +++++++++++++++++++++++++++++++ 1 files changed, 37 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index b280efb..fe88e37 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -37,6 +37,7 @@ #include #include +#include #define DA850_EVM_PHY_MASK 0x1 #define DA850_EVM_MDIO_FREQUENCY 2200000 /* PHY bus frequency */ @@ -48,6 +49,28 @@ #define DA850_MII_MDIO_CLKEN_PIN GPIO_TO_PIN(2, 6) + +#define DAVINCI_BACKLIGHT_MAX_BRIGHTNESS 250 +#define DAVINVI_BACKLIGHT_DEFAULT_BRIGHTNESS 250 +#define DAVINCI_PWM_PERIOD_NANO_SECONDS (1000000 * 10) + +static struct platform_pwm_backlight_data da850evm_backlight_data = { + .pwm_id = "ecap.2", + .ch = 0, + .max_brightness = DAVINCI_BACKLIGHT_MAX_BRIGHTNESS, + .dft_brightness = DAVINVI_BACKLIGHT_DEFAULT_BRIGHTNESS, + .pwm_period_ns = DAVINCI_PWM_PERIOD_NANO_SECONDS, +}; + +static struct platform_device da850evm_backlight = { + .name = "pwm-backlight", + .id = -1, + .dev = { + .platform_data = &da850evm_backlight_data, + }, +}; + + static struct mtd_partition da850_evm_norflash_partition[] = { { .name = "bootloaders + env", @@ -633,6 +656,20 @@ static int __init da850_evm_config_emac(void) pr_warning("da850_evm_init: emac registration failed: %d\n", ret); + ret = davinci_cfg_reg(DA850_ECAP2_APWM2); + if (ret) + pr_warning("da850_evm_init:ecap mux failed: %d\n", ret); + + ret = da850_register_ecap(); + if (ret) + pr_warning("da850_evm_init: eCAP registration failed: %d\n", + ret); + + ret = platform_device_register(&da850evm_backlight); + if (ret) + pr_warning("da850_evm_init: backlight device registration " + "failed: %d\n", ret); + return 0; } device_initcall(da850_evm_config_emac); -- 1.5.6 From nikai at nikai.net Mon Oct 4 05:39:47 2010 From: nikai at nikai.net (Nicolas Kaiser) Date: Mon, 4 Oct 2010 12:39:47 +0200 Subject: [PATCH 5/5] arm/davinci: remove duplicated include In-Reply-To: <20101004122436.7092868f@absol.kitzblitz> References: <20101004122436.7092868f@absol.kitzblitz> Message-ID: <20101004123947.1e89128f@absol.kitzblitz> Remove duplicated include. Signed-off-by: Nicolas Kaiser --- arch/arm/mach-davinci/board-da850-evm.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index fdc2cc5..851cc45 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include -- 1.7.2.2 From vitalywool at gmail.com Fri Oct 8 01:44:33 2010 From: vitalywool at gmail.com (Vitaly Wool) Date: Fri, 8 Oct 2010 07:44:33 +0100 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> <4CADE1B8.50800@mvista.com> Message-ID: On Fri, Oct 8, 2010 at 5:54 AM, Nori, Sekhar wrote: > Hi Sergei, > > On Thu, Oct 07, 2010 at 20:35:28, Sergei Shtylyov wrote: > >> > +static void da830_evm_nor_done(void *data) >> > +{ >> > + ? clk_disable(da830_evm_nor.clk); >> > + ? clk_put(da830_evm_nor.clk); >> > + ? iounmap(da830_evm_nor.latch.addr); >> > + ? release_mem_region(DA8XX_AEMIF_CS3_BASE, PAGE_SIZE); >> > + ? iounmap(da830_evm_nor.aemif.addr); >> > + ? release_mem_region(DA8XX_AEMIF_CTL_BASE, SZ_32K); >> > +} >> >> ? ? Why you've changed this function which was useful also for the error cleanup >> before? > > The issues down below aside, I think goto based error handling > is clearer to follow. Any objections to using goto based > error handing per-se? What you're saying just doesn't make sense in this context. Whatever way of error handling is chosen, it first needs to be correct which is absolutely not the case here. ~Vitaly From vitalywool at gmail.com Fri Oct 8 05:51:15 2010 From: vitalywool at gmail.com (Vitaly Wool) Date: Fri, 8 Oct 2010 12:51:15 +0200 Subject: [PATCH 2/2] davinci: Platform support for OMAP-L137/AM17x NOR flash driver In-Reply-To: <4CAEEADF.5070103@mvista.com> References: <1286451272-12988-1-git-send-email-savinay.dharmappa@ti.com> <4CADE1B8.50800@mvista.com> <4CAEEADF.5070103@mvista.com> Message-ID: On Fri, Oct 8, 2010 at 11:56 AM, Sergei Shtylyov wrote: > ? I think the code was more compact with the old error handling. And anyway, > I'm not feeling happy when TI is changing MV's code. Leaving the inter-vendor relations aside, I'd say, anyone can modify any GPL code. The thing is, this person can not just inherit Signed-off-by from the previous version, and this is what happened I guess. ~Vitaly From ayildirim at aselsan.com.tr Fri Oct 8 11:11:39 2010 From: ayildirim at aselsan.com.tr (Alper YILDIRIM) Date: Fri, 8 Oct 2010 09:11:39 -0700 (PDT) Subject: [PATCH] davinci: Implement sched_clock() In-Reply-To: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> References: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> Message-ID: <1286554299908-5615499.post@n2.nabble.com> Andreas.Gaer wrote: > > From: Andreas Gaeer > > Overwrite the default implementation of sched_clock that is based on > jiffies by something more precise. This improves timestamps in ftrace. > Implementation is copied from OMAP platform code. > > Hi Andreas, does this patch improves the printk times in kernel logs? Thanks, Alper -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/PATCH-davinci-Implement-sched-clock-tp5606181p5615499.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. From khilman at deeprootsystems.com Fri Oct 8 13:17:44 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Fri, 08 Oct 2010 11:17:44 -0700 Subject: [PATCH] davinci: Implement sched_clock() In-Reply-To: <4CAEE9DA.1020900@mvista.com> (Sergei Shtylyov's message of "Fri, 08 Oct 2010 13:52:26 +0400") References: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> <87pqvm9bbv.fsf@deeprootsystems.com> <4CAEE9DA.1020900@mvista.com> Message-ID: <87mxqoy2ev.fsf@deeprootsystems.com> Sergei Shtylyov writes: > Hello. > > On 07-10-2010 21:12, Kevin Hilman wrote: > >>> Overwrite the default implementation of sched_clock that is based on >>> jiffies by something more precise. This improves timestamps in ftrace. >>> Implementation is copied from OMAP platform code. > >>> Signed-off-by: Andreas Gaeer > >> Thanks, applying to davinci git. > >> Will queue for 2.6.38 (it's a bit too late for 2.6.37 as Linus only >> wants real regression fixes after -rc6.) > > Did you mean 2.6.37 and 2.6.36 respecitvely? Nope. IOW, for the upcoming merge window (2.6.37), Linus does not want to see new features done after 2.6.36-rc6. He wants to sure that by the time the merge window opens, that things have received some testing and validation, particularily in linux-next. This means, that most maintainers (myself included) will not be taking patches/features for 2.6.N merge window after 2.6.(N-1)-rc6 is released, unless they are regression fixes. Kevin From michael.williamson at criticallink.com Fri Oct 8 14:22:46 2010 From: michael.williamson at criticallink.com (Michael Williamson) Date: Fri, 08 Oct 2010 15:22:46 -0400 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> Message-ID: <4CAF6F86.40201@criticallink.com> Hi Sekhar, On 10/6/2010 11:37 AM, Nori, Sekhar wrote: > Hi Mike, > > On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: >> >> Let me know if you want testing on the DMA portion of the patch (when your ready, of course). > > I just finished pushing the DMA related patches to the git branch[1]. > I have not tested yet, but feel free to give it a go (maybe I will get > lucky again!). > I gave it a go for our platform. The good news is, polled and interrupt driven mode still work! The bad news is that DMA mode hangs up the kernel on the first read attempt, stalled waiting for the transfer completion notification (hmmm.... I think this was a spot where things were tweaked a bit? :) ) I'll see if I can narrow it down some more if you don't get to it first. > Also, do you have patches adding SPI support for DA850 platform? > I can include these patches on this branch so others who will be > testing don?t have to repeat the work. > I cloned your repository at [1] and published the additions needed to made to test it on the mitydsp-l138 platform (da850 based) at [2] (never mind the UART one at the end). I had to add clock support for the spi devices and define the platform SPI resources/registration routines. I'd appreciate a quick peek at those to make sure that I didn't make any errors. The spi registration may be refactorable (sp?) to support da830, I didn't look to closely at that. If any of it is usable, great. > Thanks, > Sekhar > > [1] http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite > [2] http://support.criticallink.com/gitweb/?p=linux-davinci.git;a=shortlog;h=refs/heads/spi-testing -Mike From vm.rod25 at gmail.com Fri Oct 8 20:10:18 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:10:18 -0500 Subject: [PATCH v1 0/6] Add Omapl138-Hawkboard support Message-ID: <1286586618-1145-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (6): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard ASoC: davinci: ASoC support for Omapl138-Hawkboard davinci: SOUND support for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboard davinci: USB-OHCI support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 294 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 21 ++- arch/arm/mach-davinci/include/mach/mux.h | 2 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 323 insertions(+), 5 deletions(-) From vm.rod25 at gmail.com Fri Oct 8 20:10:29 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:10:29 -0500 Subject: [PATCH v1 1/6] davinci: EMAC support for Omapl138-Hawkboard Message-ID: <1286586630-1170-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..87d0aae 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,53 @@ #include #include +#include + +#define DA850_EVM_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static int __init omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return 0; + + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + pr_info("EMAC: MII PHY configured\n"); + + if (ret) + pr_warning("%s: " + "cpgmac/mii mux setup failed: %d\n", __func__, ret); + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + + soc_info->emac_pdata->phy_id = DA850_EVM_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: " + "emac registration failed: %d\n", __func__, ret); + return 0; +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:10:38 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:10:38 -0500 Subject: [PATCH v1 2/6] davinci: EDMA support for Omapl138-Hawkboard Message-ID: <1286586638-1193-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 55 +++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 87d0aae..01eef73 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -66,6 +66,56 @@ static int __init omapl138_hawk_config_emac(void) return 0; } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM, hence + * they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -77,6 +127,11 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("omapl138_hawk_init: " + "edma registration failed: %d\n", ret); + ret = omapl138_hawk_config_emac(); ret = da8xx_register_watchdog(); -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:10:49 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:10:49 -0500 Subject: [PATCH v1 3/6] ASoC: davinci: ASoC support for Omapl138-Hawkboard Message-ID: <1286586649-1272-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..d6cb394 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC&& (MACH_DAVINCI_DA850_EVM \ + || MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:12:07 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:12:07 -0500 Subject: [PATCH v1 3/6] ASoC: davinci: ASoC support for Omapl138-Hawkboard Message-ID: <1286586727-1296-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..d6cb394 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC&& (MACH_DAVINCI_DA850_EVM \ + || MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:12:26 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:12:26 -0500 Subject: [PATCH v1 4/6] davinci: SOUND support for Omapl138-Hawkboard Message-ID: <1286586746-1322-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 46 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 2 +- 2 files changed, 47 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 01eef73..ba3718a 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,37 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci da850 evm audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -134,6 +166,20 @@ static __init void omapl138_hawk_init(void) ret = omapl138_hawk_config_emac(); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("omapl138_hawk_init: " + "i2c0 registration failed: %d\n", ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("omapl138_hawk_init: " + "mcasp mux setup failed: %d\n", ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:12:45 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:12:45 -0500 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard Message-ID: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 43 +++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ba3718a..ae7f75c 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define DA850_EVM_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -149,6 +151,25 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) "mcasp mux setup failed: %d\n", ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = davinci_cfg_reg_list(da850_mmcsd0_pins); + if (ret) + pr_warning("omapl138_hawk_init: " + "mmcsd0 mux setup failed: %d\n", ret); + + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("da850_hawk_init: can not open GPIO %d\n", + DA850_HAWK_MMCSD_CD_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); + + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("da850_hawk_init: can not open GPIO %d\n", + DA850_HAWK_MMCSD_WP_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("omapl138_hawk_init: " + "mmcsd0 registration failed: %d\n", ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Fri Oct 8 20:12:59 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 8 Oct 2010 20:12:59 -0500 Subject: [PATCH v1 6/6] davinci: USB-OHCI support for Omapl138-Hawkboard Message-ID: <1286586779-1370-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB-OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB pen drive In order to connect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 101 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 19 +++++ arch/arm/mach-davinci/include/mach/mux.h | 2 + 3 files changed, 122 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ae7f75c..1864d51 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -170,6 +173,94 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2065 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -223,6 +314,16 @@ static __init void omapl138_hawk_init(void) pr_warning("omapl138_hawk_init: " "mmcsd0 registration failed: %d\n", ret); + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..1675f41 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,21 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, + .flags = ALWAYS_ENABLED, + }; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, + }; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; @@ -548,6 +565,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..e2985e6 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -913,6 +913,8 @@ enum davinci_da850_index { DA850_GPIO2_15, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO2_4, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From sshtylyov at mvista.com Sat Oct 9 07:28:42 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Sat, 09 Oct 2010 16:28:42 +0400 Subject: [PATCH v1 3/6] ASoC: davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1286586727-1296-1-git-send-email-vm.rod25@gmail.com> References: <1286586727-1296-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB05FFA.4070804@mvista.com> Hello. On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds ASoC support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig > index 6bbf001..d6cb394 100644 > --- a/sound/soc/davinci/Kconfig > +++ b/sound/soc/davinci/Kconfig > @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM > DA830/OMAP-L137 EVM > > config SND_DA850_SOC_EVM > - tristate "SoC Audio support for DA850/OMAP-L138 EVM" > - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM > + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" > + depends on SND_DAVINCI_SOC&& (MACH_DAVINCI_DA850_EVM \ Keep space before && please. > + || MACH_OMAPL138_HAWKBOARD) || should preferably be on the previous line. WBR, Sergei From sshtylyov at mvista.com Sat Oct 9 07:32:54 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Sat, 09 Oct 2010 16:32:54 +0400 Subject: [PATCH v1 4/6] davinci: SOUND support for Omapl138-Hawkboard In-Reply-To: <1286586746-1322-1-git-send-email-vm.rod25@gmail.com> References: <1286586746-1322-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB060F6.6040803@mvista.com> Hello. On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds sound support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 01eef73..ba3718a 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -116,6 +117,37 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { > &da850_edma_cc1_rsv, > }; > > +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { > + { > + I2C_BOARD_INFO("tlv320aic3x", 0x18), > + }, > +}; > + > +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { > + .bus_freq = 100, /* kHz */ > + .bus_delay = 0, /* usec */ > +}; > + > +/* davinci da850 evm audio machine driver */ > +static u8 da850_iis_serializer_direction[] = { > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, > +}; > + > +static struct snd_platform_data omapl138_hawk_snd_data = { > + .tx_dma_offset = 0x2000, > + .rx_dma_offset = 0x2000, > + .op_mode = DAVINCI_MCASP_IIS_MODE, > + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), > + .tdm_slots = 2, > + .serial_dir = da850_iis_serializer_direction, > + .asp_chan_q = EVENTQ_1, > + .version = MCASP_VERSION_2, > + .txnumevt = 1, > + .rxnumevt = 1, > +}; > > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > @@ -134,6 +166,20 @@ static __init void omapl138_hawk_init(void) > > ret = omapl138_hawk_config_emac(); > > + i2c_register_board_info(1, omapl138_hawk_i2c_devices, > + ARRAY_SIZE(omapl138_hawk_i2c_devices)); > + > + ret = da8xx_register_i2c(0,&omapl138_hawk_i2c_0_pdata); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "i2c0 registration failed: %d\n", ret); pr_warning("%s: i2c0 registration failed: %d\n", __func__, ret); > + > + ret = davinci_cfg_reg_list(da850_mcasp_pins); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "mcasp mux setup failed: %d\n", ret); pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 63916b9..f033a0a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { > const short da850_mcasp_pins[] __initdata = { > DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, > DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, > - DA850_AXR_11, DA850_AXR_12, > + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, > -1 > }; Hm, should probably be a sperate patch... WBR, Sergei From sshtylyov at mvista.com Sat Oct 9 07:38:53 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Sat, 09 Oct 2010 16:38:53 +0400 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard In-Reply-To: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> References: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB0625D.4040507@mvista.com> Hello. On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds MMC/SD support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index ba3718a..ae7f75c 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) > "mcasp mux setup failed: %d\n", ret); > da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > > + ret = davinci_cfg_reg_list(da850_mmcsd0_pins); No, you can't use the generic pin list. You should add to it the two GPIOs used as WP/CD inputs, and define the new list in the board file. > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "mmcsd0 mux setup failed: %d\n", ret); pr_warning("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret); > + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); > + if (ret) > + pr_warning("da850_hawk_init: can not open GPIO %d\n", > + DA850_HAWK_MMCSD_CD_PIN); pr_warning("%s: can not open GPIO %d\n", __func__, DA850_HAWK_MMCSD_CD_PIN); > + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); > + > + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); > + if (ret) > + pr_warning("da850_hawk_init: can not open GPIO %d\n", > + DA850_HAWK_MMCSD_WP_PIN); pr_warning("%s: can not open GPIO %d\n", __func__, DA850_HAWK_MMCSD_WP_PIN); > + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); > + > + ret = da8xx_register_mmcsd0(&da850_mmc_config); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "mmcsd0 registration failed: %d\n", ret); pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); WBR, Sergei From michael.williamson at criticallink.com Sat Oct 9 07:55:54 2010 From: michael.williamson at criticallink.com (Michael Williamson) Date: Sat, 09 Oct 2010 08:55:54 -0400 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: <4CAF6F86.40201@criticallink.com> References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> <4CAF6F86.40201@criticallink.com> Message-ID: <4CB0665A.3000309@criticallink.com> On 10/08/2010 03:22 PM, Michael Williamson wrote: > Hi Sekhar, > > On 10/6/2010 11:37 AM, Nori, Sekhar wrote: > >> Hi Mike, >> >> On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: >>> >>> Let me know if you want testing on the DMA portion of the patch (when your ready, of course). >> >> I just finished pushing the DMA related patches to the git branch[1]. >> I have not tested yet, but feel free to give it a go (maybe I will get >> lucky again!). >> > > > I gave it a go for our platform. The good news is, polled and interrupt driven mode still work! > The bad news is that DMA mode hangs up the kernel on the first read attempt, stalled waiting > for the transfer completion notification (hmmm.... I think this was a spot where things were > tweaked a bit? :) ) > > I'll see if I can narrow it down some more if you don't get to it first. > I think I found it. This patch (below, and on [2]) got it working for me. The Rx DMA size on transfer requests with no receive buffer provided needs to match the requested size (and the transmit size), not the size of the temporary buffer. All good as the DMA address increment is 0 in this case. I'll try to do some more testing next week, but so far so good. --- diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 662ebbe..8206df1 100755 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -632,13 +632,11 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) * source address never increments. */ - if (t->rx_buf) { + rx_buf_count = davinci_spi->rcount; + if (t->rx_buf) rx_buf = t->rx_buf; - rx_buf_count = davinci_spi->rcount; - } else { + else rx_buf = davinci_spi->rx_tmp_buf; - rx_buf_count = sizeof(davinci_spi->rx_tmp_buf); - } t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count, DMA_FROM_DEVICE); > >> Also, do you have patches adding SPI support for DA850 platform? >> I can include these patches on this branch so others who will be >> testing dont have to repeat the work. >> > > > I cloned your repository at [1] and published the additions needed to made to test it on the > mitydsp-l138 platform (da850 based) at [2] (never mind the UART one at the end). I had to add > clock support for the spi devices and define the platform SPI resources/registration routines. > I'd appreciate a quick peek at those to make sure that I didn't make any errors. The spi > registration may be refactorable (sp?) to support da830, I didn't look to closely at that. > > If any of it is usable, great. > >> Thanks, >> Sekhar >> >> [1] http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite >> > > > [2] http://support.criticallink.com/gitweb/?p=linux-davinci.git;a=shortlog;h=refs/heads/spi-testing > > -Mike From sshtylyov at mvista.com Sat Oct 9 07:55:06 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Sat, 09 Oct 2010 16:55:06 +0400 Subject: [PATCH v1 6/6] davinci: USB-OHCI support for Omapl138-Hawkboard In-Reply-To: <1286586779-1370-1-git-send-email-vm.rod25@gmail.com> References: <1286586779-1370-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB0662A.8@mvista.com> Hello. On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds USB-OHCI support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index ae7f75c..1864d51 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -170,6 +173,94 @@ static struct davinci_mmc_config da850_mmc_config = { [...] > +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) > +{ > + int irq = gpio_to_irq(DA850_USB1_OC_PIN); > + int error = 0; > + > + if (handler != NULL) { > + hawk_usb_ocic_handler = handler; > + > + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, > + IRQF_DISABLED | IRQF_TRIGGER_RISING | > + IRQF_TRIGGER_FALLING, > + "OHCI over-current indicator", NULL); Please aling all follow-up lines, preferrably under 'irq'. > + if (error) > + printk(KERN_ERR "%s: could not request IRQ to watch " > + "over-current indicator changes\n", __func__); > + } else > + free_irq(irq, NULL); > + > + return error; > +} > + > +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { > + .set_power = hawk_usb_set_power, > + .get_power = hawk_usb_get_power, > + .get_oci = hawk_usb_get_oci, > + .ocic_notify = hawk_usb_ocic_notify, > + /* TPS2065 switch @ 5V */ > + .potpgt = (3 + 1) / 2, /* 3 ms max */ Are you really using the same power switch chip as DA830 EVM? > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index f033a0a..1675f41 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -345,6 +345,21 @@ static struct clk aemif_clk = { > .flags = ALWAYS_ENABLED, > }; > > +static struct clk usb11_clk = { > + .name = "usb11", > + .parent = &pll0_sysclk4, > + .lpsc = DA8XX_LPSC1_USB11, > + .gpsc = 1, > + .flags = ALWAYS_ENABLED, > + }; > + > +static struct clk usb20_clk = { > + .name = "usb20", > + .parent = &pll0_sysclk2, > + .lpsc = DA8XX_LPSC1_USB20, > + .gpsc = 1, > + }; > + > static struct clk_lookup da850_clks[] = { > CLK(NULL, "ref", &ref_clk), > CLK(NULL, "pll0", &pll0_clk), > @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { > CLK("davinci_mmc.0", NULL, &mmcsd0_clk), > CLK("davinci_mmc.1", NULL, &mmcsd1_clk), > CLK(NULL, "aemif", &aemif_clk), > + CLK(NULL, "usb11", &usb11_clk), > + CLK(NULL, "usb20", &usb20_clk), > CLK(NULL, NULL, NULL), > }; > > @@ -548,6 +565,8 @@ static const struct mux_config da850_pins[] = { > MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) > MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) > MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) > + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) > + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) > MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) > #endif > }; > diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h > index de11aac..e2985e6 100644 > --- a/arch/arm/mach-davinci/include/mach/mux.h > +++ b/arch/arm/mach-davinci/include/mach/mux.h > @@ -913,6 +913,8 @@ enum davinci_da850_index { > DA850_GPIO2_15, > DA850_GPIO4_0, > DA850_GPIO4_1, > + DA850_GPIO2_4, > + DA850_GPIO6_13, > DA850_RTC_ALARM, > }; > The above should be a separate patch (or even 2 patches). WBR, Sergei From Andreas.Gaer at baslerweb.com Mon Oct 11 02:11:37 2010 From: Andreas.Gaer at baslerweb.com (Gaer, A.) Date: Mon, 11 Oct 2010 09:11:37 +0200 Subject: AW: [PATCH] davinci: Implement sched_clock() In-Reply-To: <1286554299908-5615499.post@n2.nabble.com> References: <1286354335-31819-1-git-send-email-Andreas.Gaer@baslerweb.com> <1286554299908-5615499.post@n2.nabble.com> Message-ID: Hi Alper, > does this patch improves the printk times in kernel logs? yes, it also improves printk times. Regards, Andreas. From gasparini at imavis.com Mon Oct 11 03:44:34 2010 From: gasparini at imavis.com (Andrea Gasparini) Date: Mon, 11 Oct 2010 10:44:34 +0200 Subject: net example? Message-ID: <201010111044.34563.gasparini@imavis.com> Hi, perhaps a recurring question: is there an example of a net driver that makes heavy use of edma ? thank, bye! -- Andrea Gasparini ---- ImaVis S.r.l. ---- web: www.imavis.com From lamiaposta71 at gmail.com Mon Oct 11 05:10:33 2010 From: lamiaposta71 at gmail.com (Raffaele Recalcati) Date: Mon, 11 Oct 2010 12:10:33 +0200 Subject: problem with serial console In-Reply-To: References: <2A3DCF3DA181AD40BDE86A3150B27B6B0356476D44@dbde02.ent.ti.com> Message-ID: On Mon, Oct 4, 2010 at 11:57 AM, kunal singh wrote: > Hi all, > > ? I have not been able to fix the issue with early printk. I still believe > that it is not supported in the 2.6.32 open source kernel for davinci. > ? However, I was able to fix problem with the kernel (by trial and error) > and kernel boot is ok now. How did you fix it? Something about earlycon? Thx > > ? Thanks every one for your help on this issue. > > Regards, > Kunal > > On Sun, Oct 3, 2010 at 10:46 AM, kunal singh wrote: >> >> While doing the early console set up, there is a function call to >> drivers/serial/8250_early.c/serial8250_find_port_For_earlycon() >> >> The above function always returns with an error condition. It does checks >> on the early_device and these checks fail (it fails because the >> early_device.port is un-initialized). >> >> I checked the code and see that early_device (which is a static variable) >> is never intialzed any where in the code drivers/serial/8250_early.c. I >> wonder if the earlycon support has been added for 2.6.32 kernel? any >> suggestions? >> >> On Thu, Sep 30, 2010 at 9:18 PM, kunal singh >> wrote: >>> >>> Tried with earlyprintk, but the problem persists >>> >>> On Thu, Sep 30, 2010 at 8:45 PM, kunal singh >>> wrote: >>>> >>>> Hi Hemant, >>>> >>>> ?? No I have not added the earlyprintk. I will investigate this. Shall I >>>> add earlyprintk=serial,uart0 ? >>>> >>>> ? BTW, I tried to trace down the printk code flow in kernel/printk.c. >>>> ? (1) in the function _call_console_drivers(), __call_console_drivers() >>>> never gets called [the if() condition is never met]. >>>> ? (2) May be it probably explains why nothing gets printed on serial? Is >>>> this because there is no earlyprintk in bootargs? >>>> >>>> Regards, >>>> kunal >>>> >>>> >>>> >>>> >>>> On Thu, Sep 30, 2010 at 8:19 PM, Pedanekar, Hemant >>>> wrote: >>>>> >>>>> Just to check: have you added "earlyprintk" to your bootargs? >>>>> >>>>> - >>>>> Hemant >>>>> >>>>> >>>>> >>>>> ________________________________ >>>>> From: kunal singh [mailto:paheliprasad at gmail.com] >>>>> Sent: Thursday, September 30, 2010 7:40 PM >>>>> To: Raffaele Recalcati; Nori, Sekhar; Pedanekar, Hemant >>>>> Cc: davinci-linux-open-source at linux.davincidsp.com >>>>> Subject: Re: problem with serial console >>>>> >>>>> Hi All, >>>>> >>>>> >>>>> ?Thanks a lot for posting the comments here. >>>>> >>>>> ?(1) I have added some printascii() statements in function >>>>> init/main.c/start_kernel() to trace the boot sequence >>>>> ???? (a) printascii() to print the command line arguments >>>>> ???? (b) printascii() before doing the console_init() >>>>> ???? (c) printascii() after doing the console_init() >>>>> >>>>> ?(2)? The log (posted below) suggests that the boot sequence goes >>>>> beyond console_init(). Since console_init is done I would expect that all my >>>>> printk messages should start to appear on the console . But it does not. >>>>> (however the printascii still works, as you can see messages in the bootlog, >>>>> hence I would assume that hardware is fine) >>>>> >>>>> ?? I would appreciate if you can give some suggestion on how to debug >>>>> this issue further. >>>>> >>>>> Thanks, >>>>> kunal >>>>> >>>>> >>>>> /************* HERE IS THE BOOT LOG ****************************/ >>>>> run devboot >>>>> TFTP from server 10.0.0.1; our IP address is 10.0.0.3 >>>>> Filename '/home/kunal/xcaster/ingenient-bsp/images/uImage'. >>>>> Load address: 0x82000000 >>>>> Loading: #T >>>>> ################################################################ >>>>> >>>>> ################################################################# >>>>> ???????? #################T >>>>> ################################################ >>>>> >>>>> ################################################################## >>>>> ???????? ###################T ##########T >>>>> #################################### >>>>> ???????? ##########################################T #### >>>>> done >>>>> Bytes transferred = 1898780 (1cf91c hex) >>>>> ## Booting image at 82000000 ... >>>>> ?? Image Name:?? Linux-2.6.32-rc2-davinci1 >>>>> ?? Image Type:?? ARM Linux Kernel Image (uncompressed) >>>>> ?? Data Size:??? 1898716 Bytes =? 1.8 MB >>>>> ?? Load Address: 80008000 >>>>> ?? Entry Point:? 80008000 >>>>> ?? Verifying Checksum ... OK >>>>> OK >>>>> >>>>> Starting kernel ... >>>>> >>>>> Uncompressing >>>>> Linux........................................................................................................................... >>>>> done, booting the kernel. >>>>> >>>>> console=ttyS0,115200n8 root=/dev/nfs rw >>>>> nfsroot=10.0.0.1:/home/kunal/xcaster/ingenient-bsp/rootfs/fs,udp,v3,rsize=4096,wsize=1400 >>>>> ip=10.0.0.3:10.0.0.1:10.0.0.1:255.255.255.0:XCASTER5000::off mem=128M >>>>> mtdparts=davinci-nand.0:96k(ubl),736k(uboot),64k(uboot-env),2m(kernel),61568k(app) >>>>> eth=80:4C:EF:54:87:0A >>>>> doing console init now >>>>> finished console init >>>>> >>>>> /***************************************************************/ >>>>> >>>>> >>>>> On Thu, Sep 30, 2010 at 6:26 PM, Raffaele Recalcati >>>>> wrote: >>>>>> >>>>>> On Thu, Sep 30, 2010 at 2:35 PM, kunal singh >>>>>> wrote: >>>>>> > Hi Raffaele, >>>>>> > >>>>>> > ? Thanks for the suggestion. >>>>>> > >>>>>> > ?(1)? Console is fine. I am able to communicate with the u-boot >>>>>> > (115200,n8). >>>>>> > Also if I use printascii (a kernel function) I am able to output on >>>>>> > console. >>>>>> > ?(2) There is no message, after the kernel decompression (because >>>>>> > console is >>>>>> > not up). Here is what I see. >>>>>> > >>>>>> > Load address: 0x82000000 >>>>>> > Loading: ####T ###################T >>>>>> > ########################################## >>>>>> > >>>>>> > ################################################################## >>>>>> > ???????? ######################T >>>>>> > ############################################ >>>>>> > >>>>>> > ################################################################# >>>>>> > ???????? ###################T >>>>>> > ##############################################T ## >>>>>> > ???????? ######T ######################################## >>>>>> > done >>>>>> > Bytes transferred = 1898828 (1cf94c hex) >>>>>> > ## Booting image at 82000000 ... >>>>>> > ?? Image Name:?? Linux-2.6.32-rc2-davinci1 >>>>>> > ?? Image Type:?? ARM Linux Kernel Image (uncompressed) >>>>>> > ?? Data Size:??? 1898764 Bytes =? 1.8 MB >>>>>> > ?? Load Address: 80008000 >>>>>> > ?? Entry Point:? 80008000 >>>>>> > ?? Verifying Checksum ... OK >>>>>> > OK >>>>>> > >>>>>> > Starting kernel ... >>>>>> > >>>>>> > Uncompressing >>>>>> > >>>>>> > Linux........................................................................................................................... >>>>>> > done, booting the kernel. >>>>>> > >>>>>> > /* AND THEN NOTHING BECAUSE CONSOLE IS NOT FUNCTIONAL, but booting >>>>>> > goes on >>>>>> > */ >>>>>> >>>>>> How can you say that boot goes on? >>>>>> Can you check mem inside bootargs? >>>>>> For instance I have 128MB RAM and I use these bootargs. >>>>>> >>>>>> set bootargs 'console=ttyS0,115200n8 rw >>>>>> ip=10.39.10.183:10.39.10.169:10.39.8.1:255.255.248.0:::off >>>>>> root=/dev/nfs nfsroot=10.39.10.169:/home/NFS/ARAGO_DEMO_IMAGE-raf/ >>>>>> mem=128M >>>>>> video=davincifb:output=lcd:format=rgb:vid0=240x320 at 0,0:vid1=240x320 at 0,0:osd0=240x320 at 0,0:osd1=240x320 at 0,0 >>>>>> ' >>>>>> >>>>>> Don't copy my bootargs, only do some tests. >>>>>> I saw your behaviour when mem was wrong. >>>>> >>>> >>> >> > > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > -- www.opensurf.it From lamiaposta71 at gmail.com Mon Oct 11 07:40:22 2010 From: lamiaposta71 at gmail.com (Raffaele Recalcati) Date: Mon, 11 Oct 2010 14:40:22 +0200 Subject: net example? In-Reply-To: <201010111044.34563.gasparini@imavis.com> References: <201010111044.34563.gasparini@imavis.com> Message-ID: On Mon, Oct 11, 2010 at 10:44 AM, Andrea Gasparini wrote: > Hi, > perhaps a recurring question: is there an example of a net driver that > makes heavy use of edma ? Normally a net driver doesn't use, it is instead used. If you are thinking about net performances you can launch on your board (ip addr = 10.39.10.183): iperf -s And from a PC: iperf -c 10.39.10.183 -w 64k (64k means 128k, due to an iperf known issue) You will need to reach the following performances, if dm365 is your case: http://processors.wiki.ti.com/index.php/DaVinci_PSP_03.01_GA_%28r37%29_Release_Notes#Performance_-_DM365_EVM The only "problem" is that the packets, arriving to dm365 board, are going to be discarded and I don't know if they are copied to the user-space. If you can do: strace iperf -s and check if the copy is done you will have the answer you need. bye, Raffaele From sureshs at silvanlabs.com Mon Oct 11 07:53:36 2010 From: sureshs at silvanlabs.com (Suresh Somasekharappa) Date: Mon, 11 Oct 2010 18:23:36 +0530 Subject: Error when using openRTSP of wis-streamer on DM365 IPNC Message-ID: Hi, I am getting an error while using the openRTSP of wis-streamer on DM365 IPNC. Please find below the details of the error. ./openRTSP -d 5 rtsp:// 192.168.1.223:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 Sending request: OPTIONS rtsp:// 192.168.1.223:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 RTSP/1.0 CSeq: 1 User-Agent: ./openRTSP (LIVE555 Streaming Media v2010.01.22) Sending request: DESCRIBE rtsp:// 192.168.1.223:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 RTSP/1.0 CSeq: 2 Accept: application/sdp User-Agent: ./openRTSP (LIVE555 Streaming Media v2010.01.22) Failed to get a SDP description from URL "rtsp:// 192.168.1.223:8556/PSIA/Streaming/channels/2?videoCodecType=H.264": Failed to read response: Success Any help will be greatly appreciated. Thanks and Regards, Suresh S -------------- next part -------------- An HTML attachment was scrubbed... URL: From gongzy_sjz at yahoo.cn Mon Oct 11 10:42:33 2010 From: gongzy_sjz at yahoo.cn (=?utf-8?B?6Ieq55Sx5Lq6?=) Date: Mon, 11 Oct 2010 23:42:33 +0800 (CST) Subject: dm6467 arm side interupt Message-ID: <956813.34745.qm@web92404.mail.cnh.yahoo.com> ????????1?i won't use linux opetation system on my dm6467 board . how can i? startup isr interrupt? someone can give me some exmaple or tell me how , thank you!? ??????? ?????2?function init_vect() in ubl ,why "volatile Uint32 *ivect = (volatile Uint32 *)0x10004" ?????? void init_vect() { #ifdef UBL_USE_NOR_BOOT ?volatile Uint32 *ivect = (volatile Uint32 *)0x10000; ?*ivect++ = 0xEAFFFFFE;? /* Reset @ 0x00*/ #else ?volatile Uint32 *ivect = (volatile Uint32 *)0x10004; #endif ?*ivect++ = 0xEAFFFFFE;? /* Undefined Address @ 0x04 */ ?*ivect++ = 0xEAFFFFFE;? /* Software Interrupt @0x08 */ ?*ivect++ = 0xEAFFFFFE;? /* Pre-Fetch Abort @ 0x0C */ ?*ivect++ = 0xEAFFFFFE;? /* Data Abort @ 0x10 */ ?*ivect++ = 0xEAFFFFFE;? /* Reserved @ 0x14 */ ?*ivect++ = 0xEAFFFFFE;? /* IRQ @ 0x18 */ ?*ivect?? = 0xEAFFFFFE;?/* FIQ @ 0x1C */ } 3?if i already write fiq isr,__my_fiq(), ?????? void init_vect() { #ifdef UBL_USE_NOR_BOOT ?volatile Uint32 *ivect = (volatile Uint32 *)0x10000; ?*ivect++ = 0xEAFFFFFE;? /* Reset @ 0x00*/ #else ?volatile Uint32 *ivect = (volatile Uint32 *)0x10004; #endif ?*ivect++ = 0xEAFFFFFE;? /* Undefined Address @ 0x04 */ ?*ivect++ = 0xEAFFFFFE;? /* Software Interrupt @0x08 */ ?*ivect++ = 0xEAFFFFFE;? /* Pre-Fetch Abort @ 0x0C */ ?*ivect++ = 0xEAFFFFFE;? /* Data Abort @ 0x10 */ ?*ivect++ = 0xEAFFFFFE;? /* Reserved @ 0x14 */ ?*ivect++ = 0xEAFFFFFE;? /* IRQ @ 0x18 */ ?*ivect?? = (unsigned long)my_fiq;?/* FIQ @ 0x1C */ } -------------- next part -------------- An HTML attachment was scrubbed... URL: From khilman at deeprootsystems.com Mon Oct 11 10:43:50 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 11 Oct 2010 08:43:50 -0700 Subject: [PATCH v1 0/6] Add Omapl138-Hawkboard support In-Reply-To: <1286586618-1145-1-git-send-email-vm.rod25@gmail.com> (vm's message of "Fri, 8 Oct 2010 20:10:18 -0500") References: <1286586618-1145-1-git-send-email-vm.rod25@gmail.com> Message-ID: <877hhospjd.fsf@deeprootsystems.com> writes: > From: Victor Rodriguez > > This patch adds > EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI > support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. Please remove these 2 sentences from all the changelogs. In addition to Sergei's comments, which I completely agree with, I have some general comments: When you cut and paste from other board files, please also update the comments. I see at least a couple places where comments in this code refers to the EVM. Also, since I don't have a hawkboard, before merging, it would be nice to see some more folks that have these boards test the various features in this series and reply with their 'Tested-by' Kevin > Victor Rodriguez (6): > davinci: EMAC support for Omapl138-Hawkboard > davinci: EDMA support for Omapl138-Hawkboard > ASoC: davinci: ASoC support for Omapl138-Hawkboard > davinci: SOUND support for Omapl138-Hawkboard > davinci: MMC/SD support for Omapl138-Hawkboard > davinci: USB-OHCI support for Omapl138-Hawkboard > > arch/arm/mach-davinci/board-omapl138-hawk.c | 294 +++++++++++++++++++++++++++ > arch/arm/mach-davinci/da850.c | 21 ++- > arch/arm/mach-davinci/include/mach/mux.h | 2 + > sound/soc/davinci/Kconfig | 5 +- > sound/soc/davinci/davinci-evm.c | 6 +- > 5 files changed, 323 insertions(+), 5 deletions(-) > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From nsekhar at ti.com Mon Oct 11 11:57:25 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 11 Oct 2010 22:27:25 +0530 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: <4CB0665A.3000309@criticallink.com> References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> <4CAF6F86.40201@criticallink.com> <4CB0665A.3000309@criticallink.com> Message-ID: Hi Mike, On Sat, Oct 09, 2010 at 18:25:54, Michael Williamson wrote: > On 10/08/2010 03:22 PM, Michael Williamson wrote: > > On 10/6/2010 11:37 AM, Nori, Sekhar wrote: > >> On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: > >> > >> I just finished pushing the DMA related patches to the git branch[1]. > >> I have not tested yet, but feel free to give it a go (maybe I will get > >> lucky again!). > >> > > > > > > I gave it a go for our platform. The good news is, polled and interrupt driven mode still work! > > The bad news is that DMA mode hangs up the kernel on the first read attempt, stalled waiting > > for the transfer completion notification (hmmm.... I think this was a spot where things were > > tweaked a bit? :) ) > > > > I'll see if I can narrow it down some more if you don't get to it first. > > > > I think I found it. This patch (below, and on [2]) got it working for me. The Rx DMA > size on transfer requests with no receive buffer provided needs to match the requested > size (and the transmit size), not the size of the temporary buffer. All good as the > DMA address increment is 0 in this case. > > I'll try to do some more testing next week, but so far so good. Sorry, I couldn?t get to testing even today. Should be on it tomorrow. > > --- > diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c > index 662ebbe..8206df1 100755 > --- a/drivers/spi/davinci_spi.c > +++ b/drivers/spi/davinci_spi.c > @@ -632,13 +632,11 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) > * source address never increments. > */ > > - if (t->rx_buf) { > + rx_buf_count = davinci_spi->rcount; > + if (t->rx_buf) > rx_buf = t->rx_buf; > - rx_buf_count = davinci_spi->rcount; > - } else { > + else > rx_buf = davinci_spi->rx_tmp_buf; > - rx_buf_count = sizeof(davinci_spi->rx_tmp_buf); > - } > > t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count, > DMA_FROM_DEVICE); Hmm, looks like the Tx and Rx DMA must always run for the same duration. I was under the impression Tx is required to keep the clock running, and so must always run for the length of transfer requested, but Rx DMA can finish earlier. I guess replacing the line: param.a_b_cnt = rx_buf_count << 16 | data_type; with param.a_b_cnt = davinci_spi->rcount << 16 | data_type; will also fix the issue? > > > > >> Also, do you have patches adding SPI support for DA850 platform? > >> I can include these patches on this branch so others who will be > >> testing dont have to repeat the work. > >> > > > > > > I cloned your repository at [1] and published the additions needed to made to test it on the > > mitydsp-l138 platform (da850 based) at [2] (never mind the UART one at the end). I had to add > > clock support for the spi devices and define the platform SPI resources/registration routines. > > I'd appreciate a quick peek at those to make sure that I didn't make any errors. The spi > > registration may be refactorable (sp?) to support da830, I didn't look to closely at that. > > > > If any of it is usable, great. Sure it is! I checked-in your patches with some modifications to my branch. The most notable change being usage of da8xx instead of da850 since the same code should work on da830 as well. Apart from this there are some cosmetic changes (patches squashed, some non-relevant hunks dropped etc). Do update the patches in your tree if you are OK with the changes. Thanks, Sekhar From vm.rod25 at gmail.com Mon Oct 11 12:08:56 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 11 Oct 2010 12:08:56 -0500 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard In-Reply-To: <4CB0625D.4040507@mvista.com> References: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> <4CB0625D.4040507@mvista.com> Message-ID: On Sat, Oct 9, 2010 at 7:38 AM, Sergei Shtylyov wrote: > Hello. > > On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds MMC/SD support for the Hawkboard-L138 system >> It is under the machine name "omapl138_hawkboard". >> This system is based on the da850 davinci CPU architecture. > >> Signed-off-by: Victor Rodriguez > > [...] > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index ba3718a..ae7f75c 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > [...] >> >> @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) >> ? ? ? ? ? ? ? ? ? ? ? ?"mcasp mux setup failed: %d\n", ret); >> ? ? ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >> >> + ? ? ? ret = davinci_cfg_reg_list(da850_mmcsd0_pins); > > ? No, you can't use the generic pin list. You should add to it the two GPIOs > used as WP/CD inputs, and define the new list in the board file. Ok but will have to also modify the more files The other patch could be (please omit the board-omapl138-hawk.c modification that will be changed in just one patch it is just for compare previous and possible code) --- arch/arm/mach-davinci/board-omapl138-hawk.c | 9 ++++++++- arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/include/mach/mux.h | 2 ++ 3 files changed, 12 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 4a39249..8a9f9c0 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -151,6 +151,13 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + static int da850_hawk_mmc_get_ro(int index) { return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); @@ -200,7 +207,7 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); - ret = davinci_cfg_reg_list(da850_mmcsd0_pins); + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); if (ret) pr_warning("%s: MMC/SD0 mux setup failed: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..7787f5a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..e043f11 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -913,6 +913,8 @@ enum davinci_da850_index { DA850_GPIO2_15, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_RTC_ALARM, }; -- 1.6.0.5 I could make tow more pathces one for arch/arm/mach-davinci/da850.c | 2 ++ and other for arch/arm/mach-davinci/include/mach/mux.h | 2 ++ Is this Ok ? I have tested with these changes and it works perfect Thanks and regards Victor Rodriguez >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " >> + ? ? ? ? ? ? ? ? ? ? ? "mmcsd0 mux setup failed: %d\n", ret); > > ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 mux setup failed: %d\n", > ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, ret); > >> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("da850_hawk_init: can not open GPIO %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DA850_HAWK_MMCSD_CD_PIN); > > ? ? ? ? ? ? ? ?pr_warning("%s: can not open GPIO %d\n", > ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_CD_PIN); > >> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); >> + >> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("da850_hawk_init: can not open GPIO %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DA850_HAWK_MMCSD_WP_PIN); > > ? ? ? ? ? ? ? ?pr_warning("%s: can not open GPIO %d\n", > ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_WP_PIN); > >> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); >> + >> + ? ? ? ret = da8xx_register_mmcsd0(&da850_mmc_config); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " >> + ? ? ? ? ? ? ? ? ? ? ? "mmcsd0 registration failed: %d\n", ret); > > ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 registration failed: %d\n", > ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, ret); > > WBR, Sergei > From vm.rod25 at gmail.com Mon Oct 11 12:22:57 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 11 Oct 2010 12:22:57 -0500 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard In-Reply-To: References: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> <4CB0625D.4040507@mvista.com> Message-ID: On Mon, Oct 11, 2010 at 12:08 PM, Victor Rodriguez wrote: > On Sat, Oct 9, 2010 at 7:38 AM, Sergei Shtylyov wrote: >> Hello. >> >> On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: >> >>> From: Victor Rodriguez >> >>> This patch adds MMC/SD support for the Hawkboard-L138 system >>> It is under the machine name "omapl138_hawkboard". >>> This system is based on the da850 davinci CPU architecture. >> >>> Signed-off-by: Victor Rodriguez >> >> [...] >> >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index ba3718a..ae7f75c 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> >> [...] >>> >>> @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) >>> ? ? ? ? ? ? ? ? ? ? ? ?"mcasp mux setup failed: %d\n", ret); >>> ? ? ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >>> >>> + ? ? ? ret = davinci_cfg_reg_list(da850_mmcsd0_pins); >> >> ? No, you can't use the generic pin list. You should add to it the two GPIOs >> used as WP/CD inputs, and define the new list in the board file. > > > Ok but will have to also modify the more files > > The other patch could be (please omit the ?board-omapl138-hawk.c > modification that will be changed in just one patch it is just for > compare previous and ?possible code) > --- > ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? ?9 ++++++++- > ?arch/arm/mach-davinci/da850.c ? ? ? ? ? ? ? | ? ?2 ++ > ?arch/arm/mach-davinci/include/mach/mux.h ? ?| ? ?2 ++ > ?3 files changed, 12 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 4a39249..8a9f9c0 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -151,6 +151,13 @@ static struct snd_platform_data omapl138_hawk_snd_data = { > ? ? ? ?.rxnumevt ? ? ? = 1, > ?}; > > +static const short hawk_mmcsd0_pins[] = { > + ? ? ? DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, > + ? ? ? DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, > + ? ? ? DA850_GPIO3_12, DA850_GPIO3_13, > + ? ? ? -1 > +}; > + > ?static int da850_hawk_mmc_get_ro(int index) > ?{ > ? ? ? ?return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); > @@ -200,7 +207,7 @@ static __init void omapl138_hawk_init(void) > ? ? ? ? ? ? ? ?pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); > ? ? ? ?da8xx_regisv9/v2/0002-davinci-MMC-SD-pins-support-for-Omapl138-Hawkboar.patchter_mcasp(0, &omapl138_hawk_snd_data); > > - ? ? ? ret = davinci_cfg_reg_list(da850_mmcsd0_pins); > + ? ? ? ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); > ? ? ? ?if (ret) > ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 mux setup failed: %d\n", > ? ? ? ? ? ? ? ? ? ? ? ?__func__, ret); > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index f033a0a..7787f5a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { > ? ? ? ?MUX_CFG(DA850, GPIO2_15, ? ? ? ?5, ? ? ?0, ? ? ?15, ? ? 8, ? ? ?false) > ? ? ? ?MUX_CFG(DA850, GPIO4_0, ? ? ? ? 10, ? ? 28, ? ? 15, ? ? 8, ? ? ?false) > ? ? ? ?MUX_CFG(DA850, GPIO4_1, ? ? ? ? 10, ? ? 24, ? ? 15, ? ? 8, ? ? ?false) > + ? ? ? MUX_CFG(DA850, GPIO3_12, ? ? ? ?7, ? ? ?12, ? ? 15, ? ? 8, ? ? ?false) > + ? ? ? MUX_CFG(DA850, GPIO3_13, ? ? ? ?7, ? ? ?8, ? ? ?15, ? ? 8, ? ? ?false) > ? ? ? ?MUX_CFG(DA850, RTC_ALARM, ? ? ? 0, ? ? ?28, ? ? 15, ? ? 2, ? ? ?false) > ?#endif > ?}; > diff --git a/arch/arm/mach-davinci/include/mach/mux.h > b/arch/arm/mach-davinci/include/mach/mux.h > index de11aac..e043f11 100644 > --- a/arch/arm/mach-davinci/include/mach/mux.h > +++ b/arch/arm/mach-davinci/include/mach/mux.h > @@ -913,6 +913,8 @@ enum davinci_da850_index { > ? ? ? ?DA850_GPIO2_15, > ? ? ? ?DA850_GPIO4_0, > ? ? ? ?DA850_GPIO4_1, > + ? ? ? DA850_GPIO3_12, > + ? ? ? DA850_GPIO3_13, > ? ? ? ?DA850_RTC_ALARM, > ?}; > > -- > 1.6.0.5 > > I could make tow more pathces one for > ?arch/arm/mach-davinci/da850.c ? ? ? ? ? ? ? | ? ?2 ++ > > and other ?for > > ?arch/arm/mach-davinci/include/mach/mux.h ? ?| ? ?2 ++ > > > Is this Ok ? > > I have tested with these changes and it works perfect > > Thanks and regards > > Victor Rodriguez > > >>> + ? ? ? if (ret) >>> + ? ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " >>> + ? ? ? ? ? ? ? ? ? ? ? "mmcsd0 mux setup failed: %d\n", ret); >> >> ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 mux setup failed: %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> >>> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); >>> + ? ? ? if (ret) >>> + ? ? ? ? ? ? ? pr_warning("da850_hawk_init: can not open GPIO %d\n", >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DA850_HAWK_MMCSD_CD_PIN); >> >> ? ? ? ? ? ? ? ?pr_warning("%s: can not open GPIO %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_CD_PIN); >> >>> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); >>> + >>> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); >>> + ? ? ? if (ret) >>> + ? ? ? ? ? ? ? pr_warning("da850_hawk_init: can not open GPIO %d\n", >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DA850_HAWK_MMCSD_WP_PIN); >> >> ? ? ? ? ? ? ? ?pr_warning("%s: can not open GPIO %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_WP_PIN); >> >>> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); >>> + >>> + ? ? ? ret = da8xx_register_mmcsd0(&da850_mmc_config); >>> + ? ? ? if (ret) >>> + ? ? ? ? ? ? ? pr_warning("omapl138_hawk_init: " >>> + ? ? ? ? ? ? ? ? ? ? ? "mmcsd0 registration failed: %d\n", ret); >> >> ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 registration failed: %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> >> WBR, Sergei >> > Sergei the final patch could be Subject: [PATCH v2] davinci: MMC/SD pins support for Omapl138-Hawkboar This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/include/mach/mux.h | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..7787f5a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..e043f11 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -913,6 +913,8 @@ enum davinci_da850_index { DA850_GPIO2_15, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_RTC_ALARM, }; -- 1.6.0.5 And Subject: [PATCH v2] davinci: MMC/SD support for Omapl138-Hawkboar This patch adds MMC/SD support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 182f097..8a9f9c0 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define DA850_EVM_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -149,6 +151,32 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -179,6 +207,28 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); + + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 Is this ok or should make the first two patches? Thanks for check the patches Sincerely yours Victor Rodriguez From michael.williamson at criticallink.com Mon Oct 11 13:09:35 2010 From: michael.williamson at criticallink.com (Michael Williamson) Date: Mon, 11 Oct 2010 14:09:35 -0400 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> <4CAF6F86.40201@criticallink.com> <4CB0665A.3000309@criticallink.com> Message-ID: <4CB352DF.70104@criticallink.com> On 10/11/2010 12:57 PM, Nori, Sekhar wrote: > Hi Mike, > > On Sat, Oct 09, 2010 at 18:25:54, Michael Williamson wrote: >> On 10/08/2010 03:22 PM, Michael Williamson wrote: > >>> On 10/6/2010 11:37 AM, Nori, Sekhar wrote: > >>>> On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: > >>>> >>>> I just finished pushing the DMA related patches to the git branch[1]. >>>> I have not tested yet, but feel free to give it a go (maybe I will get >>>> lucky again!). >>>> >>> >>> >>> I gave it a go for our platform. The good news is, polled and interrupt driven mode still work! >>> The bad news is that DMA mode hangs up the kernel on the first read attempt, stalled waiting >>> for the transfer completion notification (hmmm.... I think this was a spot where things were >>> tweaked a bit? :) ) >>> >>> I'll see if I can narrow it down some more if you don't get to it first. >>> >> >> I think I found it. This patch (below, and on [2]) got it working for me. The Rx DMA >> size on transfer requests with no receive buffer provided needs to match the requested >> size (and the transmit size), not the size of the temporary buffer. All good as the >> DMA address increment is 0 in this case. >> >> I'll try to do some more testing next week, but so far so good. > > Sorry, I couldn?t get to testing even today. Should be on it > tomorrow. > >> >> --- >> diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c >> index 662ebbe..8206df1 100755 >> --- a/drivers/spi/davinci_spi.c >> +++ b/drivers/spi/davinci_spi.c >> @@ -632,13 +632,11 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t) >> * source address never increments. >> */ >> >> - if (t->rx_buf) { >> + rx_buf_count = davinci_spi->rcount; >> + if (t->rx_buf) >> rx_buf = t->rx_buf; >> - rx_buf_count = davinci_spi->rcount; >> - } else { >> + else >> rx_buf = davinci_spi->rx_tmp_buf; >> - rx_buf_count = sizeof(davinci_spi->rx_tmp_buf); >> - } >> >> t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count, >> DMA_FROM_DEVICE); > > Hmm, looks like the Tx and Rx DMA must always run for the same duration. I was > under the impression Tx is required to keep the clock running, and so must always > run for the length of transfer requested, but Rx DMA can finish earlier. > That may be true. The scenario I was seeing was a requested Tx length of 1 with no Rx buffer supplied. The length of the internal buffer was bigger than 1, so the resulting Rx DMA size in the a_b_cnt was greater than the Tx size, and it stalled. > I guess replacing the line: > > param.a_b_cnt = rx_buf_count << 16 | data_type; > > with > > param.a_b_cnt = davinci_spi->rcount << 16 | data_type; > > will also fix the issue? > A better fix. should be fine. >> >>> >>>> Also, do you have patches adding SPI support for DA850 platform? >>>> I can include these patches on this branch so others who will be >>>> testing dont have to repeat the work. >>>> >>> >>> >>> I cloned your repository at [1] and published the additions needed to made to test it on the >>> mitydsp-l138 platform (da850 based) at [2] (never mind the UART one at the end). I had to add >>> clock support for the spi devices and define the platform SPI resources/registration routines. >>> I'd appreciate a quick peek at those to make sure that I didn't make any errors. The spi >>> registration may be refactorable (sp?) to support da830, I didn't look to closely at that. >>> >>> If any of it is usable, great. > > Sure it is! I checked-in your patches with some modifications to my > branch. The most notable change being usage of da8xx instead of da850 since > the same code should work on da830 as well. Apart from this there are > some cosmetic changes (patches squashed, some non-relevant hunks dropped > etc). Do update the patches in your tree if you are OK with the changes. > OK. I'll try to rebase off your tree and retest. -Mike From vm.rod25 at gmail.com Mon Oct 11 14:27:59 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 11 Oct 2010 14:27:59 -0500 Subject: [PATCH v1 6/6] davinci: USB-OHCI support for Omapl138-Hawkboard In-Reply-To: <4CB0662A.8@mvista.com> References: <1286586779-1370-1-git-send-email-vm.rod25@gmail.com> <4CB0662A.8@mvista.com> Message-ID: On Sat, Oct 9, 2010 at 7:55 AM, Sergei Shtylyov wrote: > Hello. > > On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds USB-OHCI support for the Hawkboard-L138 system >> It is under the machine name "omapl138_hawkboard". >> This system is based on the da850 davinci CPU architecture. > >> Signed-off-by: Victor Rodriguez > > [...] > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index ae7f75c..1864d51 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > [...] >> >> @@ -170,6 +173,94 @@ static struct davinci_mmc_config da850_mmc_config = { > > [...] >> >> +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) >> +{ >> + ? ? ? int irq ? ? ? ? = gpio_to_irq(DA850_USB1_OC_PIN); >> + ? ? ? int error ? ? ? = 0; >> + >> + ? ? ? if (handler != NULL) { >> + ? ? ? ? ? ? ? hawk_usb_ocic_handler = handler; >> + >> + ? ? ? ? ? ? ? error = request_irq(irq, omapl138_hawk_usb_ocic_irq, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_TRIGGER_RISING | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_TRIGGER_FALLING, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "OHCI over-current indicator", >> NULL); > > ? Please aling all follow-up lines, preferrably under 'irq'. Sorry I do not follow here. Under what do you suggest to align ?? static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) { int irq = gpio_to_irq(DA850_USB1_OC_PIN); int error = 0; if (handler != NULL) { hawk_usb_ocic_handler = handler; error = request_irq(irq, omapl138_hawk_usb_ocic_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) printk(KERN_ERR "%s: could not request IRQ to watch " "over-current indicator changes\n", __func__); } else free_irq(irq, NULL); return error; } >> + ? ? ? ? ? ? ? if (error) >> + ? ? ? ? ? ? ? ? ? ? ? printk(KERN_ERR "%s: could not request IRQ to >> watch " >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "over-current indicator changes\n", >> __func__); >> + ? ? ? } else >> + ? ? ? ? ? ? ? free_irq(irq, NULL); >> + >> + ? ? ? return error; >> +} >> + >> +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { >> + ? ? ? .set_power ? ? ?= hawk_usb_set_power, >> + ? ? ? .get_power ? ? ?= hawk_usb_get_power, >> + ? ? ? .get_oci ? ? ? ?= hawk_usb_get_oci, >> + ? ? ? .ocic_notify ? ?= hawk_usb_ocic_notify, >> + ? ? ? /* TPS2065 switch @ 5V */ >> + ? ? ? .potpgt ? ? ? ? = (3 + 1) / 2, ?/* 3 ms max */ > > ? Are you really using the same power switch chip as DA830 EVM? Sorry was the TPS2087D But is also at 5V with the same parameters the only minor difference that i see is that TPS2065 is * 1-A Continuous Current and TPS2087D is * 500 mA Continuous Current per Channel but works fine with that parameters Regards Victor Rodriguez could work even at >> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c >> index f033a0a..1675f41 100644 >> --- a/arch/arm/mach-davinci/da850.c >> +++ b/arch/arm/mach-davinci/da850.c >> @@ -345,6 +345,21 @@ static struct clk aemif_clk = { >> ? ? ? ?.flags ? ? ? ? ?= ALWAYS_ENABLED, >> ?}; >> >> +static struct clk usb11_clk = { >> + ? ? ? .name ? ? ? ? ? = "usb11", >> + ? ? ? .parent ? ? ? ? = &pll0_sysclk4, >> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB11, >> + ? ? ? .gpsc ? ? ? ? ? = 1, >> + ? ? ? .flags ? ? ? ? ?= ALWAYS_ENABLED, >> + ? ? ? }; >> + >> +static struct clk usb20_clk = { >> + ? ? ? .name ? ? ? ? ? = "usb20", >> + ? ? ? .parent ? ? ? ? = &pll0_sysclk2, >> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB20, >> + ? ? ? .gpsc ? ? ? ? ? = 1, >> + ? ? ? }; >> + >> ?static struct clk_lookup da850_clks[] = { >> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "ref", ? ? ? ? ?&ref_clk), >> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "pll0", ? ? ? ? &pll0_clk), >> @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { >> ? ? ? ?CLK("davinci_mmc.0", ? ?NULL, ? ? ? ? ? &mmcsd0_clk), >> ? ? ? ?CLK("davinci_mmc.1", ? ?NULL, ? ? ? ? ? &mmcsd1_clk), >> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "aemif", ? ? ? ?&aemif_clk), >> + ? ? ? CLK(NULL, ? ? ? ? ? ? ? "usb11", ? ? ? ?&usb11_clk), >> + ? ? ? CLK(NULL, ? ? ? ? ? ? ? "usb20", ? ? ? ?&usb20_clk), >> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? NULL, ? ? ? ? ? NULL), >> ?}; >> >> @@ -548,6 +565,8 @@ static const struct mux_config da850_pins[] = { >> ? ? ? ?MUX_CFG(DA850, GPIO2_15, ? ? ? ?5, ? ? ?0, ? ? ?15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, GPIO4_0, ? ? ? ? 10, ? ? 28, ? ? 15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, GPIO4_1, ? ? ? ? 10, ? ? 24, ? ? 15, ? ? 8, >> ?false) >> + ? ? ? MUX_CFG(DA850, GPIO2_4, ? ? ? ? 6, ? ? ?12, ? ? 15, ? ? 8, >> ?false) >> + ? ? ? MUX_CFG(DA850, GPIO6_13, ? ? ? ?13, ? ? 8, ? ? ?15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, RTC_ALARM, ? ? ? 0, ? ? ?28, ? ? 15, ? ? 2, >> ?false) >> ?#endif >> ?}; >> diff --git a/arch/arm/mach-davinci/include/mach/mux.h >> b/arch/arm/mach-davinci/include/mach/mux.h >> index de11aac..e2985e6 100644 >> --- a/arch/arm/mach-davinci/include/mach/mux.h >> +++ b/arch/arm/mach-davinci/include/mach/mux.h >> @@ -913,6 +913,8 @@ enum davinci_da850_index { >> ? ? ? ?DA850_GPIO2_15, >> ? ? ? ?DA850_GPIO4_0, >> ? ? ? ?DA850_GPIO4_1, >> + ? ? ? DA850_GPIO2_4, >> + ? ? ? DA850_GPIO6_13, >> ? ? ? ?DA850_RTC_ALARM, >> ?}; >> > > ? The above should be a separate patch (or even 2 patches). > > WBR, Sergei > From tk at gelo.com Mon Oct 11 16:32:59 2010 From: tk at gelo.com (Timor Knudsen) Date: Mon, 11 Oct 2010 23:32:59 +0200 Subject: UART - RTS and CTS on DA850 Message-ID: Dear List, this is not exactly a Linux related question, but I'll post it here anyway. Hopefully someone wants to help me. I built a custom carrier board for the DA850 SOM. It is very similiar to the LogicPD carrier board, but differs in using a MAX3221 instead of TRS3386 for UART interface. So I don't use CTS/RTS pins of the UART interface; the pins are floating. When I plug in the module, it won't boot (hangs) and does not print anything on UART. I checked the u-boot sources, and there is the following pin definition in board/davinci/da8xxevm/da850evm.c: /* UART pin muxer settings */ static const struct pinmux_config uart_pins[] = { { pinmux(0), 4, 6 }, { pinmux(0), 4, 7 }, { pinmux(4), 2, 4 }, { pinmux(4), 2, 5 } }; Two of those pins are RTS and CTS. Maybe the system hangs because it wants to print something on UART but is waiting for CTS? Will it be sufficient to delete the two pin definitions in u-boot? Will the board run on the original LogicPD baseboard with this u-boot modification? Thanks in advance, Timor From michael.williamson at criticallink.com Mon Oct 11 19:31:15 2010 From: michael.williamson at criticallink.com (Michael Williamson) Date: Mon, 11 Oct 2010 20:31:15 -0400 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> <4CAF6F86.40201@criticallink.com> <4CB0665A.3000309@criticallink.com> Message-ID: <4CB3AC53.2050701@criticallink.com> On 10/11/2010 12:57 PM, Nori, Sekhar wrote: > Hi Mike, > > On Sat, Oct 09, 2010 at 18:25:54, Michael Williamson wrote: >> On 10/08/2010 03:22 PM, Michael Williamson wrote: > >>> On 10/6/2010 11:37 AM, Nori, Sekhar wrote: > >>>> On Mon, Sep 20, 2010 at 23:12:53, Michael Williamson wrote: > >>>> >>>> I just finished pushing the DMA related patches to the git branch[1]. [ stuff deleted ] >> >>> >>>> Also, do you have patches adding SPI support for DA850 platform? >>>> I can include these patches on this branch so others who will be >>>> testing dont have to repeat the work. >>>> >>> >>> >>> I cloned your repository at [1] and published the additions needed to made to test it on the >>> mitydsp-l138 platform (da850 based) at [2] (never mind the UART one at the end). I had to add >>> clock support for the spi devices and define the platform SPI resources/registration routines. >>> I'd appreciate a quick peek at those to make sure that I didn't make any errors. The spi >>> registration may be refactorable (sp?) to support da830, I didn't look to closely at that. >>> >>> If any of it is usable, great. > > Sure it is! I checked-in your patches with some modifications to my > branch. The most notable change being usage of da8xx instead of da850 since > the same code should work on da830 as well. Apart from this there are > some cosmetic changes (patches squashed, some non-relevant hunks dropped > etc). Do update the patches in your tree if you are OK with the changes. > I think that the spi device names in the clk_lookup table in da830.c may need to be updated. Right now they are shown as "dm_spi.0". Should they be "spi_davinci.o" and "spi_davinci.1"? -Mike From vm.rod25 at gmail.com Mon Oct 11 20:09:00 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 11 Oct 2010 20:09:00 -0500 Subject: [PATCH v1 6/6] davinci: USB-OHCI support for Omapl138-Hawkboard In-Reply-To: References: <1286586779-1370-1-git-send-email-vm.rod25@gmail.com> <4CB0662A.8@mvista.com> Message-ID: On Mon, Oct 11, 2010 at 2:27 PM, Victor Rodriguez wrote: > On Sat, Oct 9, 2010 at 7:55 AM, Sergei Shtylyov wrote: >> Hello. >> >> On 09-10-2010 5:12, vm.rod25 at gmail.com wrote: >> >>> From: Victor Rodriguez >> >>> This patch adds USB-OHCI support for the Hawkboard-L138 system >>> It is under the machine name "omapl138_hawkboard". >>> This system is based on the da850 davinci CPU architecture. >> >>> Signed-off-by: Victor Rodriguez >> >> [...] >> >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index ae7f75c..1864d51 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> >> [...] >>> >>> @@ -170,6 +173,94 @@ static struct davinci_mmc_config da850_mmc_config = { >> >> [...] >>> >>> +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) >>> +{ >>> + ? ? ? int irq ? ? ? ? = gpio_to_irq(DA850_USB1_OC_PIN); >>> + ? ? ? int error ? ? ? = 0; >>> + >>> + ? ? ? if (handler != NULL) { >>> + ? ? ? ? ? ? ? hawk_usb_ocic_handler = handler; >>> + >>> + ? ? ? ? ? ? ? error = request_irq(irq, omapl138_hawk_usb_ocic_irq, >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | IRQF_TRIGGER_RISING | >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_TRIGGER_FALLING, >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "OHCI over-current indicator", >>> NULL); >> >> ? Please aling all follow-up lines, preferrably under 'irq'. > > > Sorry I do not follow here. Under what do you suggest to align ?? > > > static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) > { > ? ? ? ?int irq ? ? ? ? = gpio_to_irq(DA850_USB1_OC_PIN); > ? ? ? ?int error ? ? ? = 0; > > ? ? ? ?if (handler != NULL) { > ? ? ? ? ? ? ? ?hawk_usb_ocic_handler = handler; > > ? ? ? ? ? ? ? ?error = request_irq(irq, omapl138_hawk_usb_ocic_irq, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IRQF_DISABLED | IRQF_TRIGGER_RISING | > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IRQF_TRIGGER_FALLING, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"OHCI over-current indicator", NULL); > ? ? ? ? ? ? ? ?if (error) > ? ? ? ? ? ? ? ? ? ? ? ?printk(KERN_ERR "%s: could not request IRQ to watch " > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"over-current indicator changes\n", __func__); > ? ? ? ?} else > ? ? ? ? ? ? ? ?free_irq(irq, NULL); > > ? ? ? ?return error; > } I think that this is what you explained static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) { int irq = gpio_to_irq(DA850_USB1_OC_PIN); int error = 0; if (handler != NULL) { hawk_usb_ocic_handler = handler; error = request_irq(irq, omapl138_hawk_usb_ocic_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) printk(KERN_ERR "%s: could not request IRQ to watch " "over-current indicator changes\n", __func__); } else free_irq(irq, NULL); return error; } Hope it will be i will send the patch Thanks a lot for check the patches Sincerely yours Victor Rodriguez >>> + ? ? ? ? ? ? ? if (error) >>> + ? ? ? ? ? ? ? ? ? ? ? printk(KERN_ERR "%s: could not request IRQ to >>> watch " >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "over-current indicator changes\n", >>> __func__); >>> + ? ? ? } else >>> + ? ? ? ? ? ? ? free_irq(irq, NULL); >>> + >>> + ? ? ? return error; >>> +} >>> + >>> +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { >>> + ? ? ? .set_power ? ? ?= hawk_usb_set_power, >>> + ? ? ? .get_power ? ? ?= hawk_usb_get_power, >>> + ? ? ? .get_oci ? ? ? ?= hawk_usb_get_oci, >>> + ? ? ? .ocic_notify ? ?= hawk_usb_ocic_notify, >>> + ? ? ? /* TPS2065 switch @ 5V */ >>> + ? ? ? .potpgt ? ? ? ? = (3 + 1) / 2, ?/* 3 ms max */ >> >> ? Are you really using the same power switch chip as DA830 EVM? > > Sorry was the > > TPS2087D > > But is also at 5V with the same parameters the only minor difference > that i see is that > > TPS2065 is > > ? ?* 1-A Continuous Current > > and TPS2087D is > > ? ?* 500 mA Continuous Current per Channel > > but works fine with that parameters > > Regards > > Victor Rodriguez > > > > could work even at >>> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c >>> index f033a0a..1675f41 100644 >>> --- a/arch/arm/mach-davinci/da850.c >>> +++ b/arch/arm/mach-davinci/da850.c >>> @@ -345,6 +345,21 @@ static struct clk aemif_clk = { >>> ? ? ? ?.flags ? ? ? ? ?= ALWAYS_ENABLED, >>> ?}; >>> >>> +static struct clk usb11_clk = { >>> + ? ? ? .name ? ? ? ? ? = "usb11", >>> + ? ? ? .parent ? ? ? ? = &pll0_sysclk4, >>> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB11, >>> + ? ? ? .gpsc ? ? ? ? ? = 1, >>> + ? ? ? .flags ? ? ? ? ?= ALWAYS_ENABLED, >>> + ? ? ? }; >>> + >>> +static struct clk usb20_clk = { >>> + ? ? ? .name ? ? ? ? ? = "usb20", >>> + ? ? ? .parent ? ? ? ? = &pll0_sysclk2, >>> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB20, >>> + ? ? ? .gpsc ? ? ? ? ? = 1, >>> + ? ? ? }; >>> + >>> ?static struct clk_lookup da850_clks[] = { >>> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "ref", ? ? ? ? ?&ref_clk), >>> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "pll0", ? ? ? ? &pll0_clk), >>> @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { >>> ? ? ? ?CLK("davinci_mmc.0", ? ?NULL, ? ? ? ? ? &mmcsd0_clk), >>> ? ? ? ?CLK("davinci_mmc.1", ? ?NULL, ? ? ? ? ? &mmcsd1_clk), >>> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? "aemif", ? ? ? ?&aemif_clk), >>> + ? ? ? CLK(NULL, ? ? ? ? ? ? ? "usb11", ? ? ? ?&usb11_clk), >>> + ? ? ? CLK(NULL, ? ? ? ? ? ? ? "usb20", ? ? ? ?&usb20_clk), >>> ? ? ? ?CLK(NULL, ? ? ? ? ? ? ? NULL, ? ? ? ? ? NULL), >>> ?}; >>> >>> @@ -548,6 +565,8 @@ static const struct mux_config da850_pins[] = { >>> ? ? ? ?MUX_CFG(DA850, GPIO2_15, ? ? ? ?5, ? ? ?0, ? ? ?15, ? ? 8, >>> ?false) >>> ? ? ? ?MUX_CFG(DA850, GPIO4_0, ? ? ? ? 10, ? ? 28, ? ? 15, ? ? 8, >>> ?false) >>> ? ? ? ?MUX_CFG(DA850, GPIO4_1, ? ? ? ? 10, ? ? 24, ? ? 15, ? ? 8, >>> ?false) >>> + ? ? ? MUX_CFG(DA850, GPIO2_4, ? ? ? ? 6, ? ? ?12, ? ? 15, ? ? 8, >>> ?false) >>> + ? ? ? MUX_CFG(DA850, GPIO6_13, ? ? ? ?13, ? ? 8, ? ? ?15, ? ? 8, >>> ?false) >>> ? ? ? ?MUX_CFG(DA850, RTC_ALARM, ? ? ? 0, ? ? ?28, ? ? 15, ? ? 2, >>> ?false) >>> ?#endif >>> ?}; >>> diff --git a/arch/arm/mach-davinci/include/mach/mux.h >>> b/arch/arm/mach-davinci/include/mach/mux.h >>> index de11aac..e2985e6 100644 >>> --- a/arch/arm/mach-davinci/include/mach/mux.h >>> +++ b/arch/arm/mach-davinci/include/mach/mux.h >>> @@ -913,6 +913,8 @@ enum davinci_da850_index { >>> ? ? ? ?DA850_GPIO2_15, >>> ? ? ? ?DA850_GPIO4_0, >>> ? ? ? ?DA850_GPIO4_1, >>> + ? ? ? DA850_GPIO2_4, >>> + ? ? ? DA850_GPIO6_13, >>> ? ? ? ?DA850_RTC_ALARM, >>> ?}; >>> >> >> ? The above should be a separate patch (or even 2 patches). >> >> WBR, Sergei >> > From vm.rod25 at gmail.com Mon Oct 11 22:52:35 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:52:35 -0500 Subject: [PATCH v2 00/10] Add Omapl138-Hawkboard support Message-ID: <1286855555-31712-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (10): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard davinci: ASoC support for Omapl138-Hawkboard davinci: McASP configuration for Omapl138-Hawkboard davinci: Audio support for Omapl138-Hawkboard davinci: MMC/SD configuration for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboar davinci: USB1.1 clocks for Omapl138-Hawkboard davinci: USB1.1 GPIOs for Omapl138-Hawkboard davinci: USB-OHCI support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 300 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 23 ++- arch/arm/mach-davinci/include/mach/mux.h | 4 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 333 insertions(+), 5 deletions(-) From vm.rod25 at gmail.com Mon Oct 11 22:53:32 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:53:32 -0500 Subject: [PATCH v2 01/10] davinci: EMAC support for Omapl138-Hawkboard Message-ID: <1286855612-31735-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..3ae5178 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,53 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static int __init omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return 0; + + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + pr_info("EMAC: MII PHY configured\n"); + + if (ret) + pr_warning("%s: " + "cpgmac/mii mux setup failed: %d\n", __func__, ret); + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: " + "emac registration failed: %d\n", __func__, ret); + return 0; +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:53:40 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:53:40 -0500 Subject: [PATCH v2 02/10] davinci: EDMA support for Omapl138-Hawkboard Message-ID: <1286855620-31758-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 55 +++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 3ae5178..358944b 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -66,6 +66,56 @@ static int __init omapl138_hawk_config_emac(void) return 0; } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -77,6 +127,11 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("omapl138_hawk_init: " + "edma registration failed: %d\n", ret); + ret = omapl138_hawk_config_emac(); ret = da8xx_register_watchdog(); -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:54:49 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:54:49 -0500 Subject: [PATCH v2 03/10] davinci: ASoC support for Omapl138-Hawkboard Message-ID: <1286855689-31787-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..72c6752 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ + MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:54:59 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:54:59 -0500 Subject: [PATCH v2 04/10] davinci: McASP configuration for Omapl138-Hawkboard Message-ID: <1286855699-31810-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration for MacASP used on the Hawkboard-L138 system in order to add Audio support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:55:07 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:55:07 -0500 Subject: [PATCH v2 05/10] davinci: Audio support for Omapl138-Hawkboard Message-ID: <1286855707-31833-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 45 +++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 358944b..c0a999a 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,37 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci Hawkboard audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -134,6 +166,19 @@ static __init void omapl138_hawk_init(void) ret = omapl138_hawk_config_emac(); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("%s: i2c0 registration failed: %d\n", + __func__, ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:55:29 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:55:29 -0500 Subject: [PATCH v2 06/10] davinci: MMC/SD configuration for Omapl138-Hawkboard Message-ID: <1286855729-31856-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration to enable MMC/SD on the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/include/mach/mux.h | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..7787f5a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..e043f11 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -913,6 +913,8 @@ enum davinci_da850_index { DA850_GPIO2_15, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:56:34 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:56:34 -0500 Subject: [PATCH v2 07/10] davinci: MMC/SD support for Omapl138-Hawkboar Message-ID: <1286855794-31879-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c0a999a..723ac03 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define HAWKBOARD_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -149,6 +151,32 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -179,6 +207,28 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); + + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:57:20 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:57:20 -0500 Subject: [PATCH v2 08/10] davinci: USB1.1 clocks for Omapl138-Hawkboard Message-ID: <1286855840-31902-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 clocks for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 7787f5a..12afb25 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,21 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, + .flags = ALWAYS_ENABLED, + }; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, + }; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:57:25 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:57:25 -0500 Subject: [PATCH v2 09/10] davinci: USB1.1 GPIOs for Omapl138-Hawkboard Message-ID: <1286855845-31925-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch enables USB1.1 GPIOs for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 ++ arch/arm/mach-davinci/include/mach/mux.h | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 12afb25..77801ed 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -567,6 +567,8 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index e043f11..f2c2117 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -915,6 +915,8 @@ enum davinci_da850_index { DA850_GPIO4_1, DA850_GPIO3_12, DA850_GPIO3_13, + DA850_GPIO2_4, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 22:57:43 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 22:57:43 -0500 Subject: [PATCH v2 10/10] davinci: USB-OHCI support for Omapl138-Hawkboard Message-ID: <1286855863-31948-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB-OHCI support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB-pen drive In order to conect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 101 +++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 723ac03..bac29fc 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -177,6 +180,94 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -229,6 +320,16 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 23:00:42 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 23:00:42 -0500 Subject: [PATCH v2 10/10] davinci: USB-OHCI support for Omapl138-Hawkboard Message-ID: <1286856042-32017-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB-OHCI support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB-pen drive In order to conect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 101 +++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 723ac03..bac29fc 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -177,6 +180,94 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -229,6 +320,16 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Mon Oct 11 23:02:11 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Mon, 11 Oct 2010 23:02:11 -0500 Subject: [PATCH v2 10/10] davinci: USB-OHCI support for Omapl138-Hawkboard Message-ID: <1286856131-32040-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB-OHCI support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB-pen drive In order to conect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 101 +++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 723ac03..bac29fc 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -177,6 +180,94 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -229,6 +320,16 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From jon.povey at racelogic.co.uk Mon Oct 11 23:47:05 2010 From: jon.povey at racelogic.co.uk (Jon Povey) Date: Tue, 12 Oct 2010 13:47:05 +0900 Subject: [PATCH] i2c: davinci: Fix TX setup for more SoCs Message-ID: <1286858825-21540-1-git-send-email-jon.povey@racelogic.co.uk> This patch is an improvement to 4bba0fd8d1c6d405df666e2573e1a1f917098be0 which got to mainline a little early. Sudhakar Rajashekhara explains that at least OMAP-L138 requires MDR mode settings before DXR for correct behaviour, so load MDR first with STT cleared and later load again with STT set. Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 Signed-off-by: Jon Povey Acked-by: Troy Kisky Tested-by: Sudhakar Rajashekhara Acked-by: Kevin Hilman --- This patches to what was v4 of the original patch. The original patch which made it to 2.6.36-rc7 will as I understand it have introduced a regression for OMAP-L138 so this patch is a regression fix and wants to get into 2.6.36. drivers/i2c/busses/i2c-davinci.c | 24 +++++++++++++++--------- 1 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index b8feac5..5795c83 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -331,21 +331,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) INIT_COMPLETION(dev->cmd_complete); dev->cmd_err = 0; - /* Take I2C out of reset, configure it as master and set the - * start bit */ - flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; + /* Take I2C out of reset and configure it as master */ + flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST; /* if the slave address is ten bit address, enable XA bit */ if (msg->flags & I2C_M_TEN) flag |= DAVINCI_I2C_MDR_XA; if (!(msg->flags & I2C_M_RD)) flag |= DAVINCI_I2C_MDR_TRX; - if (stop) - flag |= DAVINCI_I2C_MDR_STP; - if (msg->len == 0) { + if (msg->len == 0) flag |= DAVINCI_I2C_MDR_RM; - flag &= ~DAVINCI_I2C_MDR_STP; - } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); @@ -358,17 +353,28 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->terminate = 0; /* + * Write mode register first as needed for correct behaviour + * on OMAP-L138, but don't set STT yet to avoid a race with XRDY + * occuring before we have loaded DXR + */ + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); + + /* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and * ICDXR may have wrong data + * It also saves us one interrupt, slightly faster */ if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); dev->buf_len--; } - /* write the data into mode register; start transmitting */ + /* Set STT to begin transmit now DXR is loaded */ + flag |= DAVINCI_I2C_MDR_STT; + if (stop && msg->len != 0) + flag |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, -- 1.6.3.3 From Jon.Povey at racelogic.co.uk Mon Oct 11 23:48:53 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Tue, 12 Oct 2010 05:48:53 +0100 Subject: [PATCH v4] i2c: davinci: Fix race when setting up for TX In-Reply-To: <87hbgxapig.fsf@deeprootsystems.com> Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EEAAA9C@Cloud.RL.local> Kevin Hilman wrote: > I just noticed that it has already been pulled and is part of -rc7. > > Jon, care to submit a new patch with v4 diff and including > the acks and > tested-bys? Done and sent: Message-Id: <1286858825-21540-1-git-send-email-jon.povey at racelogic.co.uk> -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From nsekhar at ti.com Mon Oct 11 23:55:22 2010 From: nsekhar at ti.com (Sekhar Nori) Date: Tue, 12 Oct 2010 10:25:22 +0530 Subject: [PATCH] davinci: mityomapl138: make file local data static Message-ID: <1286859322-25412-1-git-send-email-nsekhar@ti.com> Most of the regulator data structures are local to the board file, but not made static. Fix this. Also make the nand partition table static. This gets rid of all the sparse warnings for this file. Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/board-mityomapl138.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 65f7501..194a15f 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -93,14 +93,14 @@ static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { /* TPS65023 voltage regulator support */ /* 1.2V Core */ -struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { +static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { { .supply = "cvdd", }, }; /* 1.8V */ -struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { +static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { { .supply = "usb0_vdda18", }, @@ -116,7 +116,7 @@ struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { }; /* 1.2V */ -struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { +static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { { .supply = "sata_vdd", }, @@ -132,20 +132,20 @@ struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { }; /* 1.8V Aux LDO, not used */ -struct regulator_consumer_supply tps65023_ldo1_consumers[] = { +static struct regulator_consumer_supply tps65023_ldo1_consumers[] = { { .supply = "1.8v_aux", }, }; /* FPGA VCC Aux (2.5 or 3.3) LDO */ -struct regulator_consumer_supply tps65023_ldo2_consumers[] = { +static struct regulator_consumer_supply tps65023_ldo2_consumers[] = { { .supply = "vccaux", }, }; -struct regulator_init_data tps65023_regulator_data[] = { +static struct regulator_init_data tps65023_regulator_data[] = { /* dcdc1 */ { .constraints = { @@ -226,7 +226,7 @@ static int __init pmic_tps65023_init(void) * MityDSP-L138 includes a 256 MByte large-page NAND flash * (128K blocks). */ -struct mtd_partition mityomapl138_nandflash_partition[] = { +static struct mtd_partition mityomapl138_nandflash_partition[] = { { .name = "rootfs", .offset = 0, -- 1.6.2.4 From nsekhar at ti.com Tue Oct 12 07:14:27 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Tue, 12 Oct 2010 17:44:27 +0530 Subject: [PATCH v5 1/1] davinci: spi: replace existing driver In-Reply-To: <4CB352DF.70104@criticallink.com> References: <1280355490-11878-1-git-send-email-bniebuhr@efjohnson.com> <4C8EB795.1080607@criticallink.com> <201009140904.59555.caglarakyuz@gmail.com> <4C8F7460.6050006@criticallink.com> <4C94B9BD.4010606@criticallink.com> <4C979D1D.1070707@criticallink.com> <4CAF6F86.40201@criticallink.com> <4CB0665A.3000309@criticallink.com> <4CB352DF.70104@criticallink.com> Message-ID: Hi Mike, On Mon, Oct 11, 2010 at 23:39:35, Michael Williamson wrote: > > > > Hmm, looks like the Tx and Rx DMA must always run for the same duration. I was > > under the impression Tx is required to keep the clock running, and so must always > > run for the length of transfer requested, but Rx DMA can finish earlier. > > > > That may be true. The scenario I was seeing was a requested Tx length of 1 with no > Rx buffer supplied. The length of the internal buffer was bigger than 1, so the resulting > Rx DMA size in the a_b_cnt was greater than the Tx size, and it stalled. > > > I guess replacing the line: > > > > param.a_b_cnt = rx_buf_count << 16 | data_type; > > > > with > > > > param.a_b_cnt = davinci_spi->rcount << 16 | data_type; > > > > will also fix the issue? > > > > A better fix. should be fine. I tested this on DA830 and DA850 EVMs with SPI nor flash - it works fine. I added your Tested-By to the DMA patches as well. Thanks for the testing and bug fixing. Updated set of patches pushed to my branch[1]. Testing on DM* platforms is the next task. Thanks, Sekhar [1] http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite From khilman at deeprootsystems.com Tue Oct 12 10:13:07 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Tue, 12 Oct 2010 08:13:07 -0700 Subject: [PATCH] i2c: davinci: Fix TX setup for more SoCs In-Reply-To: <1286858825-21540-1-git-send-email-jon.povey@racelogic.co.uk> (Jon Povey's message of "Tue, 12 Oct 2010 13:47:05 +0900") References: <1286858825-21540-1-git-send-email-jon.povey@racelogic.co.uk> Message-ID: <87mxqj30n0.fsf@deeprootsystems.com> Ben, Jon Povey writes: > This patch is an improvement to 4bba0fd8d1c6d405df666e2573e1a1f917098be0 > which got to mainline a little early. > > Sudhakar Rajashekhara explains that at least OMAP-L138 requires MDR mode > settings before DXR for correct behaviour, so load MDR first with > STT cleared and later load again with STT set. > > Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 > > Signed-off-by: Jon Povey > Acked-by: Troy Kisky > Tested-by: Sudhakar Rajashekhara > Acked-by: Kevin Hilman > --- > This patches to what was v4 of the original patch. > > The original patch which made it to 2.6.36-rc7 will as I understand it have > introduced a regression for OMAP-L138 so this patch is a regression fix and > wants to get into 2.6.36. can you get this one into 2.6.36 please? Thanks, Kevin > > drivers/i2c/busses/i2c-davinci.c | 24 +++++++++++++++--------- > 1 files changed, 15 insertions(+), 9 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index b8feac5..5795c83 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -331,21 +331,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > INIT_COMPLETION(dev->cmd_complete); > dev->cmd_err = 0; > > - /* Take I2C out of reset, configure it as master and set the > - * start bit */ > - flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; > + /* Take I2C out of reset and configure it as master */ > + flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST; > > /* if the slave address is ten bit address, enable XA bit */ > if (msg->flags & I2C_M_TEN) > flag |= DAVINCI_I2C_MDR_XA; > if (!(msg->flags & I2C_M_RD)) > flag |= DAVINCI_I2C_MDR_TRX; > - if (stop) > - flag |= DAVINCI_I2C_MDR_STP; > - if (msg->len == 0) { > + if (msg->len == 0) > flag |= DAVINCI_I2C_MDR_RM; > - flag &= ~DAVINCI_I2C_MDR_STP; > - } > > /* Enable receive or transmit interrupts */ > w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); > @@ -358,17 +353,28 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > dev->terminate = 0; > > /* > + * Write mode register first as needed for correct behaviour > + * on OMAP-L138, but don't set STT yet to avoid a race with XRDY > + * occuring before we have loaded DXR > + */ > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > + > + /* > * First byte should be set here, not after interrupt, > * because transmit-data-ready interrupt can come before > * NACK-interrupt during sending of previous message and > * ICDXR may have wrong data > + * It also saves us one interrupt, slightly faster > */ > if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > dev->buf_len--; > } > > - /* write the data into mode register; start transmitting */ > + /* Set STT to begin transmit now DXR is loaded */ > + flag |= DAVINCI_I2C_MDR_STT; > + if (stop && msg->len != 0) > + flag |= DAVINCI_I2C_MDR_STP; > davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > > r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, From vm.rod25 at gmail.com Tue Oct 12 10:17:22 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Tue, 12 Oct 2010 10:17:22 -0500 Subject: [PATCH v1 0/6] Add Omapl138-Hawkboard support In-Reply-To: <877hhospjd.fsf@deeprootsystems.com> References: <1286586618-1145-1-git-send-email-vm.rod25@gmail.com> <877hhospjd.fsf@deeprootsystems.com> Message-ID: On Mon, Oct 11, 2010 at 10:43 AM, Kevin Hilman wrote: > writes: > >> From: Victor Rodriguez >> >> This patch adds >> EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI >> support for the Hawkboard-L138 system > >> It is under the machine name "omapl138_hawkboard". >> This system is based on the da850 davinci CPU architecture. > > Please remove these 2 sentences from all the changelogs. > > In addition to Sergei's comments, which I completely agree with, I have > some general comments: > > When you cut and paste from other board files, please also update the > comments. ?I see at least a couple places where comments in this code > refers to the EVM. > > Also, since I don't have a hawkboard, before merging, it would be nice > to see some more folks that have these boards test the various features > in this series and reply with their 'Tested-by' > > Kevin Hi I have changed all the Segei's comments and besides the EVM comments thanks a lot for your observations. I have sanded the v2 patches with corrections Caglar i would like to ask you to check the patches. I know you have much more experience that me and you could make better observations. Thanks a lot Sincerely yours Victor Rodriguez >> Victor Rodriguez (6): >> ? davinci: EMAC support for Omapl138-Hawkboard >> ? davinci: EDMA support for Omapl138-Hawkboard >> ? ASoC: davinci: ASoC support for Omapl138-Hawkboard >> ? davinci: SOUND support for Omapl138-Hawkboard >> ? davinci: MMC/SD support for Omapl138-Hawkboard >> ? davinci: USB-OHCI support for Omapl138-Hawkboard >> >> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ?294 +++++++++++++++++++++++++++ >> ?arch/arm/mach-davinci/da850.c ? ? ? ? ? ? ? | ? 21 ++- >> ?arch/arm/mach-davinci/include/mach/mux.h ? ?| ? ?2 + >> ?sound/soc/davinci/Kconfig ? ? ? ? ? ? ? ? ? | ? ?5 +- >> ?sound/soc/davinci/davinci-evm.c ? ? ? ? ? ? | ? ?6 +- >> ?5 files changed, 323 insertions(+), 5 deletions(-) >> >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > From khilman at deeprootsystems.com Tue Oct 12 10:29:56 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Tue, 12 Oct 2010 08:29:56 -0700 Subject: [PATCH] davinci: mityomapl138: make file local data static In-Reply-To: <1286859322-25412-1-git-send-email-nsekhar@ti.com> (Sekhar Nori's message of "Tue, 12 Oct 2010 10:25:22 +0530") References: <1286859322-25412-1-git-send-email-nsekhar@ti.com> Message-ID: <87hbgr2zuz.fsf@deeprootsystems.com> Sekhar Nori writes: > Most of the regulator data structures are local to the > board file, but not made static. Fix this. > > Also make the nand partition table static. > > This gets rid of all the sparse warnings for this file. > > Signed-off-by: Sekhar Nori Thanks, applied. Kevin > --- > arch/arm/mach-davinci/board-mityomapl138.c | 14 +++++++------- > 1 files changed, 7 insertions(+), 7 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c > index 65f7501..194a15f 100644 > --- a/arch/arm/mach-davinci/board-mityomapl138.c > +++ b/arch/arm/mach-davinci/board-mityomapl138.c > @@ -93,14 +93,14 @@ static struct davinci_i2c_platform_data mityomap_i2c_0_pdata = { > > /* TPS65023 voltage regulator support */ > /* 1.2V Core */ > -struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { > +static struct regulator_consumer_supply tps65023_dcdc1_consumers[] = { > { > .supply = "cvdd", > }, > }; > > /* 1.8V */ > -struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { > +static struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { > { > .supply = "usb0_vdda18", > }, > @@ -116,7 +116,7 @@ struct regulator_consumer_supply tps65023_dcdc2_consumers[] = { > }; > > /* 1.2V */ > -struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { > +static struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { > { > .supply = "sata_vdd", > }, > @@ -132,20 +132,20 @@ struct regulator_consumer_supply tps65023_dcdc3_consumers[] = { > }; > > /* 1.8V Aux LDO, not used */ > -struct regulator_consumer_supply tps65023_ldo1_consumers[] = { > +static struct regulator_consumer_supply tps65023_ldo1_consumers[] = { > { > .supply = "1.8v_aux", > }, > }; > > /* FPGA VCC Aux (2.5 or 3.3) LDO */ > -struct regulator_consumer_supply tps65023_ldo2_consumers[] = { > +static struct regulator_consumer_supply tps65023_ldo2_consumers[] = { > { > .supply = "vccaux", > }, > }; > > -struct regulator_init_data tps65023_regulator_data[] = { > +static struct regulator_init_data tps65023_regulator_data[] = { > /* dcdc1 */ > { > .constraints = { > @@ -226,7 +226,7 @@ static int __init pmic_tps65023_init(void) > * MityDSP-L138 includes a 256 MByte large-page NAND flash > * (128K blocks). > */ > -struct mtd_partition mityomapl138_nandflash_partition[] = { > +static struct mtd_partition mityomapl138_nandflash_partition[] = { > { > .name = "rootfs", > .offset = 0, From luna.id at gmail.com Tue Oct 12 12:12:36 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Tue, 12 Oct 2010 13:12:36 -0400 Subject: OMAP-L138 to AM1808 Message-ID: Hi, I'm running Linux Davinci on a custum hardware based on OMAP L138 EVM. I got two cards, one with OMAP-L138and an other with AM1808. The only difference between the two cards is the CPU, all others peripherals are same. I compiled the kernel from DaVinci-PSP-SDK-03.20.00.12.tgz. The first board with OMAP-L138 boot correctly. With the same kernel image, the second board with AM1808 freeze at boot time. Here is the boot log: * * *Loading: #################################################################* * ################################################################# * * ################* *done* *Bytes transferred = 2142892 (20b2ac hex)* *## Booting kernel from Legacy Image at c0007fc0 ...* * Image Name: Linux-2.6.33-rc4* * Image Type: ARM Linux Kernel Image (uncompressed)* * Data Size: 2142828 Bytes = 2 MB* * Load Address: c0008000* * Entry Point: c0008000* * Verifying Checksum ... OK* * Loading Kernel Image ... OK* *OK* *Starting kernel ...* *Uncompressing Linux... done, booting the kernel. <= Freezes here !* I configured the kernel to use 300 Mhz clock, I also tried 456 Mhz but same behaviour. It seems to be a bad access to memory. Is there any access to DSP memory map in the linux kernel? Also, I tried to turn on a LED before the kernel freeze. Can anybody tell me where is the linux entry point in the code. I tried to add a raw_write into "da850_evm_map_io" and in "da850_evm_init" to turn on the LED and it doesn't work. Thank you. Regards, Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Tue Oct 12 12:19:52 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Tue, 12 Oct 2010 12:19:52 -0500 Subject: OMAP-L138 to AM1808 In-Reply-To: References: Message-ID: On Tue, Oct 12, 2010 at 12:12 PM, Nicolas Luna wrote: > Hi, > > I'm running Linux Davinci on a custum hardware based on OMAP L138 EVM. I got > two cards, one with?OMAP-L138and an other with?AM1808. The only difference > between the two cards is the CPU, all others peripherals are same. > > I compiled the kernel from?DaVinci-PSP-SDK-03.20.00.12.tgz. > > The first board with?OMAP-L138?boot correctly. > > With the same kernel image, the second board with?AM1808?freeze at boot > time. > > Here is the boot log: > > > > Loading: ################################################################# > > ?? ? ? ?? ################################################################# > > ?? ? ? ? ?################ > > done > > Bytes transferred = 2142892 (20b2ac hex) > > ## Booting kernel from Legacy Image at c0007fc0 ... > > ?? Image Name: ? Linux-2.6.33-rc4 > > ?? Image Type: ? ARM Linux Kernel Image (uncompressed) > > ?? Data Size: ? ?2142828 Bytes = ?2 MB > > ?? Load Address: c0008000 > > ?? Entry Point: ?c0008000 > > ?? Verifying Checksum ... OK > > ?? Loading Kernel Image ... OK > > OK > > Starting kernel ... > > Uncompressing Linux... done, booting the kernel.?<= Freezes here ! > Check uncompress.h and if your board is there available Besides which board are you using , i mean hawkboard? mytiomap? ... > > > > I configured the kernel to use 300 Mhz clock, I also tried 456 Mhz but same > behaviour. > > It seems to be a bad access to memory. Is there any access to DSP memory map > in the linux kernel? > > Also, I tried to turn on a LED before the kernel freeze. Can anybody tell me > where is the linux entry point in the code. I tried to add a raw_write into > "da850_evm_map_io"?and in "da850_evm_init" to turn on the LED and it doesn't > work. Check the gpio if it si maped and then make a module similar to this #define PIN_LED GPIO_TO_PIN(6, 12) #define MUX_LED DA850_GPIO6_12 static int led_on(void) { int ret; gpio_free(PIN_LED); ret = davinci_cfg_reg (MUX_LED); if (ret<0) { printk(KERN_INFO "Error\n"); return ret; } ret = gpio_request(PIN_LED, "led"); if (ret) { printk(KERN_INFO "error\n"); return ret; } gpio_direction_output(PIN_LED, 1); gpio_set_value(PIN_LED, 1); return 0 ; } Regards Victor Rodriguez > > > Thank you. > > Regards, > > Nicolas > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > From luna.id at gmail.com Tue Oct 12 12:37:48 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Tue, 12 Oct 2010 13:37:48 -0400 Subject: OMAP-L138 to AM1808 In-Reply-To: References: Message-ID: On Tue, Oct 12, 2010 at 1:19 PM, Victor Rodriguez wrote: > On Tue, Oct 12, 2010 at 12:12 PM, Nicolas Luna wrote: > > Hi, > > > > I'm running Linux Davinci on a custum hardware based on OMAP L138 EVM. I > got > > two cards, one with OMAP-L138and an other with AM1808. The only > difference > > between the two cards is the CPU, all others peripherals are same. > > > > I compiled the kernel from DaVinci-PSP-SDK-03.20.00.12.tgz. > > > > The first board with OMAP-L138 boot correctly. > > > > With the same kernel image, the second board with AM1808 freeze at boot > > time. > > > > Here is the boot log: > > > > > > > > Loading: > ################################################################# > > > > > ################################################################# > > > > ################ > > > > done > > > > Bytes transferred = 2142892 (20b2ac hex) > > > > ## Booting kernel from Legacy Image at c0007fc0 ... > > > > Image Name: Linux-2.6.33-rc4 > > > > Image Type: ARM Linux Kernel Image (uncompressed) > > > > Data Size: 2142828 Bytes = 2 MB > > > > Load Address: c0008000 > > > > Entry Point: c0008000 > > > > Verifying Checksum ... OK > > > > Loading Kernel Image ... OK > > > > OK > > > > Starting kernel ... > > > > Uncompressing Linux... done, booting the kernel. <= Freezes here ! > > > > > Check uncompress.h and if your board is there available > > It is. > > Besides which board are you using , i mean hawkboard? mytiomap? ... > Custom hardware based on OMAP-L138 EVM (ZOOM? OMAP-L138 EVM DEVELOPMENT KIT) > > > > > > > > > > I configured the kernel to use 300 Mhz clock, I also tried 456 Mhz but > same > > behaviour. > > > > It seems to be a bad access to memory. Is there any access to DSP memory > map > > in the linux kernel? > > > > Also, I tried to turn on a LED before the kernel freeze. Can anybody tell > me > > where is the linux entry point in the code. I tried to add a raw_write > into > > "da850_evm_map_io" and in "da850_evm_init" to turn on the LED and it > doesn't > > work. > > > Check the gpio if it si maped and then make a module similar to this > > #define PIN_LED GPIO_TO_PIN(6, 12) > #define MUX_LED DA850_GPIO6_12 > > static int led_on(void) > { > > > int ret; > > > gpio_free(PIN_LED); > > > ret = davinci_cfg_reg (MUX_LED); > if (ret<0) > { > printk(KERN_INFO "Error\n"); > return ret; > } > > > ret = gpio_request(PIN_LED, "led"); > if (ret) > { > printk(KERN_INFO "error\n"); > return ret; > } > > > > > gpio_direction_output(PIN_LED, 1); > > > gpio_set_value(PIN_LED, 1); > > > return 0 ; > > } > > Well, my board is freezing before all inits, it is why I tried to turn on a LED directly by writing into the GPIO register. It is working on the board why OMAP processor but with AM1808 the code seems to freeze before "da850_evm_init" so the LED doesn't turn on. The goal of this is to find where the code freeze with the LED. I wonder where I could move my code to be at the very beginning of linux startup. Regards, Nicolas > Regards > > Victor Rodriguez > > > > > > > > Thank you. > > > > Regards, > > > > Nicolas > > > > _______________________________________________ > > Davinci-linux-open-source mailing list > > Davinci-linux-open-source at linux.davincidsp.com > > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From luna.id at gmail.com Tue Oct 12 15:38:15 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Tue, 12 Oct 2010 16:38:15 -0400 Subject: OMAP-L138 to AM1808 In-Reply-To: References: Message-ID: Juha, It was exactly the problem. With the memory dump I found this ".<3>Unknown DaVinci JTAG ID 0x1b7d102f" then I changed the variant from 0 to 1 and the board booted. *To TI:* * * I checked into the AM1808 datasheet and if I follow this (see below), the variant should be 0: u16 variant; /* JTAG ID bits 31:28 */ u16 part_no; /* JTAG ID bits 27:12 */ u16 manufacturer; /* JTAG ID bits 11:1 */ AM1808 JTAG ID from datasheet: 0x0B7D_102F Is it a mistake from the datasheet? We have the ZWT package with silicon Rev B, is it have anything to do with this? Nicolas On Tue, Oct 12, 2010 at 3:31 PM, Juha Kuikka wrote: > > On Tue, Oct 12, 2010 at 10:12 AM, Nicolas Luna wrote: > >> Hi, >> >> I'm running Linux Davinci on a custum hardware based on OMAP L138 EVM. I >> got two cards, one with OMAP-L138and >> an other with AM1808. >> The only difference between the two cards is the CPU, all others peripherals >> are same. >> >> I compiled the kernel from DaVinci-PSP-SDK-03.20.00.12.tgz. >> >> The first board with OMAP-L138 boot >> correctly. >> >> With the same kernel image, the second board with AM1808 freeze >> at boot time. >> >> Here is the boot log: >> >> * >> * >> >> >> >> *Loading: >> #################################################################* >> >> * >> #################################################################* >> >> * ################* >> >> *done* >> >> *Bytes transferred = 2142892 (20b2ac hex)* >> >> *## Booting kernel from Legacy Image at c0007fc0 ...* >> >> * Image Name: Linux-2.6.33-rc4* >> >> * Image Type: ARM Linux Kernel Image (uncompressed)* >> >> * Data Size: 2142828 Bytes = 2 MB* >> >> * Load Address: c0008000* >> >> * Entry Point: c0008000* >> >> * Verifying Checksum ... OK* >> >> * Loading Kernel Image ... OK* >> >> *OK* >> >> *Starting kernel ...* >> >> *Uncompressing Linux... done, booting the kernel. <= Freezes here !* >> >> >> Hi, > > I had similar symptoms with a custom board and it turned out that the chip > (L138) variant was different. I had to add another entry with .variant = 1 > into the da850_ids[] structure in mach-davinci/da850.c. > > Just my 2c. :) > > Also, take a look at this[1] for getting access to early boot messages > without LL. > > - Juha > > [1] http://elinux.org/Kernel_Debugging_Tips#Debugging_early_boot_problems > -- > Duck tape is like the force, it has a light side and a dark side and it > holds the universe together. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben-i2c at fluff.org Tue Oct 12 17:21:18 2010 From: ben-i2c at fluff.org (Ben Dooks) Date: Tue, 12 Oct 2010 23:21:18 +0100 Subject: [PATCH] i2c: davinci: Fix TX setup for more SoCs In-Reply-To: <1286858825-21540-1-git-send-email-jon.povey@racelogic.co.uk> References: <1286858825-21540-1-git-send-email-jon.povey@racelogic.co.uk> Message-ID: <20101012222118.GX21564@trinity.fluff.org> On Tue, Oct 12, 2010 at 01:47:05PM +0900, Jon Povey wrote: > This patch is an improvement to 4bba0fd8d1c6d405df666e2573e1a1f917098be0 > which got to mainline a little early. > > Sudhakar Rajashekhara explains that at least OMAP-L138 requires MDR mode > settings before DXR for correct behaviour, so load MDR first with > STT cleared and later load again with STT set. ok, will look at sending this with tomorrow. > Tested on DM355 connected to Techwell TW2836 and Wolfson WM8985 > > Signed-off-by: Jon Povey > Acked-by: Troy Kisky > Tested-by: Sudhakar Rajashekhara > Acked-by: Kevin Hilman > --- > This patches to what was v4 of the original patch. > > The original patch which made it to 2.6.36-rc7 will as I understand it have > introduced a regression for OMAP-L138 so this patch is a regression fix and > wants to get into 2.6.36. > > drivers/i2c/busses/i2c-davinci.c | 24 +++++++++++++++--------- > 1 files changed, 15 insertions(+), 9 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c > index b8feac5..5795c83 100644 > --- a/drivers/i2c/busses/i2c-davinci.c > +++ b/drivers/i2c/busses/i2c-davinci.c > @@ -331,21 +331,16 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > INIT_COMPLETION(dev->cmd_complete); > dev->cmd_err = 0; > > - /* Take I2C out of reset, configure it as master and set the > - * start bit */ > - flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST | DAVINCI_I2C_MDR_STT; > + /* Take I2C out of reset and configure it as master */ > + flag = DAVINCI_I2C_MDR_IRS | DAVINCI_I2C_MDR_MST; > > /* if the slave address is ten bit address, enable XA bit */ > if (msg->flags & I2C_M_TEN) > flag |= DAVINCI_I2C_MDR_XA; > if (!(msg->flags & I2C_M_RD)) > flag |= DAVINCI_I2C_MDR_TRX; > - if (stop) > - flag |= DAVINCI_I2C_MDR_STP; > - if (msg->len == 0) { > + if (msg->len == 0) > flag |= DAVINCI_I2C_MDR_RM; > - flag &= ~DAVINCI_I2C_MDR_STP; > - } > > /* Enable receive or transmit interrupts */ > w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); > @@ -358,17 +353,28 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) > dev->terminate = 0; > > /* > + * Write mode register first as needed for correct behaviour > + * on OMAP-L138, but don't set STT yet to avoid a race with XRDY > + * occuring before we have loaded DXR > + */ > + davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > + > + /* > * First byte should be set here, not after interrupt, > * because transmit-data-ready interrupt can come before > * NACK-interrupt during sending of previous message and > * ICDXR may have wrong data > + * It also saves us one interrupt, slightly faster > */ > if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { > davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); > dev->buf_len--; > } > > - /* write the data into mode register; start transmitting */ > + /* Set STT to begin transmit now DXR is loaded */ > + flag |= DAVINCI_I2C_MDR_STT; > + if (stop && msg->len != 0) > + flag |= DAVINCI_I2C_MDR_STP; > davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); > > r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, > -- > 1.6.3.3 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- -- Ben Q: What's a light-year? A: One-third less calories than a regular year. From yuvraj.pasi at nextbitcpu.com Wed Oct 13 06:51:14 2010 From: yuvraj.pasi at nextbitcpu.com (Yuvraj Pasi) Date: Wed, 13 Oct 2010 17:21:14 +0530 Subject: VIDENC1_process takes 40 ms Message-ID: Hi, We are using our custom made board based on DM6446. using dvsdk 2.00.00.22 & codec engine 2.23.1 & dvsdk combo 2.05. My problem is when i am encoding a PAL resolution frame (720x576) with h.264 encoder it is taking about 40ms to encode this frame . the VIDENC1_process() takes about this much time. I checked by getting system time using struct timeval . Now if i encode only video then it gives 25 frames/sec but I need to add audio encode & put it in Transport stream packet. When i do this it start dropping frames & the actual frame rate comes down to 15 frames/sec. I also tried VIDENC1_processAsync() but then it takes the same time when i call VIDENC1_processWait() function it takes the same 40 ms to return the buffer. Please help thanks & regards yuvraj pasi -- Thanks & regards yuvraj pasi -------------- next part -------------- An HTML attachment was scrubbed... URL: From nsekhar at ti.com Wed Oct 13 12:15:38 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Wed, 13 Oct 2010 22:45:38 +0530 Subject: OMAP-L138 to AM1808 In-Reply-To: References: Message-ID: Hi Nicolas, On Wed, Oct 13, 2010 at 02:08:15, Nicolas Luna wrote: > Juha, > > It was exactly the problem. With the memory dump I found this > ".<3>Unknown DaVinci JTAG ID 0x1b7d102f" then I changed the variant from > 0 to 1 and the board booted. > > To TI: > > > I checked into the AM1808 datasheet and if I follow this (see below), > the variant should be 0: > > u16 variant; /* JTAG ID bits 31:28 */ > u16 part_no; /* JTAG ID bits 27:12 */ > u16 manufacturer; /* JTAG ID bits 11:1 */ > > AM1808 JTAG ID from datasheet: 0x0B7D_102F > > Is it a mistake from the datasheet? We have the ZWT package with > silicon Rev B, is it have anything to do with this? > I am checking with the hardware folks on this. Thanks, Sekhar From sshtylyov at mvista.com Wed Oct 13 12:33:39 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 13 Oct 2010 21:33:39 +0400 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard In-Reply-To: References: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> <4CB0625D.4040507@mvista.com> Message-ID: <4CB5ED73.50704@mvista.com> Hello. On 10/11/10 21:08, Victor Rodriguez wrote: >>> From: Victor Rodriguez >>> This patch adds MMC/SD support for the Hawkboard-L138 system >>> It is under the machine name "omapl138_hawkboard". >>> This system is based on the da850 davinci CPU architecture. >>> Signed-off-by: Victor Rodriguez >> [...] >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index ba3718a..ae7f75c 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> [...] >>> @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) >>> "mcasp mux setup failed: %d\n", ret); >>> da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >>> >>> + ret = davinci_cfg_reg_list(da850_mmcsd0_pins); >> No, you can't use the generic pin list. You should add to it the two GPIOs >> used as WP/CD inputs, and define the new list in the board file. > Ok but will have to also modify the more files > The other patch could be (please omit the board-omapl138-hawk.c > modification that will be changed in just one patch it is just for > compare previous and possible code) > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 9 ++++++++- > arch/arm/mach-davinci/da850.c | 2 ++ > arch/arm/mach-davinci/include/mach/mux.h | 2 ++ > 3 files changed, 12 insertions(+), 1 deletions(-) > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 4a39249..8a9f9c0 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -151,6 +151,13 @@ static struct snd_platform_data omapl138_hawk_snd_data = { > .rxnumevt = 1, > }; > +static const short hawk_mmcsd0_pins[] = { > + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, > + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, > + DA850_GPIO3_12, DA850_GPIO3_13, > + -1 > +}; > + > static int da850_hawk_mmc_get_ro(int index) > { > return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); > @@ -200,7 +207,7 @@ static __init void omapl138_hawk_init(void) > pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); > da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > > - ret = davinci_cfg_reg_list(da850_mmcsd0_pins); > + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); > if (ret) > pr_warning("%s: MMC/SD0 mux setup failed: %d\n", > __func__, ret); > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index f033a0a..7787f5a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { > MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) > MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) > MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) > + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) > + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) > MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) > #endif > }; > diff --git a/arch/arm/mach-davinci/include/mach/mux.h > b/arch/arm/mach-davinci/include/mach/mux.h > index de11aac..e043f11 100644 > --- a/arch/arm/mach-davinci/include/mach/mux.h > +++ b/arch/arm/mach-davinci/include/mach/mux.h > @@ -913,6 +913,8 @@ enum davinci_da850_index { > DA850_GPIO2_15, > DA850_GPIO4_0, > DA850_GPIO4_1, > + DA850_GPIO3_12, > + DA850_GPIO3_13, > DA850_RTC_ALARM, > }; > I could make tow more pathces one for > arch/arm/mach-davinci/da850.c | 2 ++ > and other for > arch/arm/mach-davinci/include/mach/mux.h | 2 ++ > Is this Ok ? No, this should be one patch. And you may also join it with the USB 1.1 GPIO PinMux definitions patch. WBR, Sergei From vm.rod25 at gmail.com Wed Oct 13 15:33:49 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Wed, 13 Oct 2010 15:33:49 -0500 Subject: [PATCH v1 5/6] davinci: MMC/SD support for Omapl138-Hawkboard In-Reply-To: <4CB5ED73.50704@mvista.com> References: <1286586765-1347-1-git-send-email-vm.rod25@gmail.com> <4CB0625D.4040507@mvista.com> <4CB5ED73.50704@mvista.com> Message-ID: On Wed, Oct 13, 2010 at 12:33 PM, Sergei Shtylyov wrote: > Hello. > > On 10/11/10 21:08, Victor Rodriguez wrote: > >>>> From: Victor Rodriguez > >>>> This patch adds MMC/SD support for the Hawkboard-L138 system >>>> It is under the machine name "omapl138_hawkboard". >>>> This system is based on the da850 davinci CPU architecture. > >>>> Signed-off-by: Victor Rodriguez > >>> [...] > >>>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> index ba3718a..ae7f75c 100644 >>>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > >>> [...] > >>>> @@ -180,6 +201,28 @@ static __init void omapl138_hawk_init(void) >>>> ? ? ? ? ? ? ? ? ? ? ? ?"mcasp mux setup failed: %d\n", ret); >>>> ? ? ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >>>> >>>> + ? ? ? ret = davinci_cfg_reg_list(da850_mmcsd0_pins); > >>> ? No, you can't use the generic pin list. You should add to it the two >>> GPIOs >>> used as WP/CD inputs, and define the new list in the board file. > > >> Ok but will have to also modify the more files > >> The other patch could be (please omit the ?board-omapl138-hawk.c >> modification that will be changed in just one patch it is just for >> compare previous and ?possible code) >> --- >> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? ?9 ++++++++- >> ?arch/arm/mach-davinci/da850.c ? ? ? ? ? ? ? | ? ?2 ++ >> ?arch/arm/mach-davinci/include/mach/mux.h ? ?| ? ?2 ++ >> ?3 files changed, 12 insertions(+), 1 deletions(-) > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index 4a39249..8a9f9c0 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -151,6 +151,13 @@ static struct snd_platform_data >> omapl138_hawk_snd_data = { >> ? ? ? ?.rxnumevt ? ? ? = 1, >> ?}; > >> +static const short hawk_mmcsd0_pins[] = { >> + ? ? ? DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, >> + ? ? ? DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, >> + ? ? ? DA850_GPIO3_12, DA850_GPIO3_13, >> + ? ? ? -1 >> +}; >> + >> ?static int da850_hawk_mmc_get_ro(int index) >> ?{ >> ? ? ? ?return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); >> @@ -200,7 +207,7 @@ static __init void omapl138_hawk_init(void) >> ? ? ? ? ? ? ? ?pr_warning("%s: mcasp mux setup failed: %d\n", __func__, >> ret); >> ? ? ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); >> >> - ? ? ? ret = davinci_cfg_reg_list(da850_mmcsd0_pins); >> + ? ? ? ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); >> ? ? ? ?if (ret) >> ? ? ? ? ? ? ? ?pr_warning("%s: MMC/SD0 mux setup failed: %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ?__func__, ret); >> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c >> index f033a0a..7787f5a 100644 >> --- a/arch/arm/mach-davinci/da850.c >> +++ b/arch/arm/mach-davinci/da850.c >> @@ -548,6 +548,8 @@ static const struct mux_config da850_pins[] = { >> ? ? ? ?MUX_CFG(DA850, GPIO2_15, ? ? ? ?5, ? ? ?0, ? ? ?15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, GPIO4_0, ? ? ? ? 10, ? ? 28, ? ? 15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, GPIO4_1, ? ? ? ? 10, ? ? 24, ? ? 15, ? ? 8, >> ?false) >> + ? ? ? MUX_CFG(DA850, GPIO3_12, ? ? ? ?7, ? ? ?12, ? ? 15, ? ? 8, >> ?false) >> + ? ? ? MUX_CFG(DA850, GPIO3_13, ? ? ? ?7, ? ? ?8, ? ? ?15, ? ? 8, >> ?false) >> ? ? ? ?MUX_CFG(DA850, RTC_ALARM, ? ? ? 0, ? ? ?28, ? ? 15, ? ? 2, >> ?false) >> ?#endif >> ?}; >> diff --git a/arch/arm/mach-davinci/include/mach/mux.h >> b/arch/arm/mach-davinci/include/mach/mux.h >> index de11aac..e043f11 100644 >> --- a/arch/arm/mach-davinci/include/mach/mux.h >> +++ b/arch/arm/mach-davinci/include/mach/mux.h >> @@ -913,6 +913,8 @@ enum davinci_da850_index { >> ? ? ? ?DA850_GPIO2_15, >> ? ? ? ?DA850_GPIO4_0, >> ? ? ? ?DA850_GPIO4_1, >> + ? ? ? DA850_GPIO3_12, >> + ? ? ? DA850_GPIO3_13, >> ? ? ? ?DA850_RTC_ALARM, >> ?}; > > >> I could make tow more pathces one for >> ?arch/arm/mach-davinci/da850.c ? ? ? ? ? ? ? | ? ?2 ++ > >> and other ?for > >> ?arch/arm/mach-davinci/include/mach/mux.h ? ?| ? ?2 ++ > > >> Is this Ok ? > > ? No, this should be one patch. And you may also join it with the USB 1.1 > GPIO PinMux definitions patch. > > WBR, Sergei > OK so if there is any other observation i could send all the other patches as v3 today. One more question is necessary to resend all the patches to both lists davinci and ALSA or just the related to sound and ALSA files ? Thanks Regards Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 14 12:21:32 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:21:32 -0500 Subject: [PATCH v3 0/9] Add Omapl138-Hawkboard support Message-ID: <1287076892-4342-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (9): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard davinci: ASoC support for Omapl138-Hawkboard davinci: McASP configuration for Omapl138-Hawkboard davinci: Audio support for Omapl138-Hawkboard davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboar davinci: USB clocks for Omapl138-Hawkboard davinci: USB-OHCI support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 300 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 23 ++- arch/arm/mach-davinci/include/mach/mux.h | 4 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 333 insertions(+), 5 deletions(-) From vm.rod25 at gmail.com Thu Oct 14 12:21:39 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:21:39 -0500 Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard Message-ID: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..3ae5178 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,53 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static int __init omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return 0; + + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + pr_info("EMAC: MII PHY configured\n"); + + if (ret) + pr_warning("%s: " + "cpgmac/mii mux setup failed: %d\n", __func__, ret); + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: " + "emac registration failed: %d\n", __func__, ret); + return 0; +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:21:46 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:21:46 -0500 Subject: [PATCH v3 2/9] davinci: EDMA support for Omapl138-Hawkboard Message-ID: <1287076906-4388-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 55 +++++++++++++++++++++++++++ 1 files changed, 55 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 3ae5178..358944b 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -66,6 +66,56 @@ static int __init omapl138_hawk_config_emac(void) return 0; } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -77,6 +127,11 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("omapl138_hawk_init: " + "edma registration failed: %d\n", ret); + ret = omapl138_hawk_config_emac(); ret = da8xx_register_watchdog(); -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:21:52 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:21:52 -0500 Subject: [PATCH v3 3/9] davinci: ASoC support for Omapl138-Hawkboard Message-ID: <1287076912-4411-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..72c6752 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ + MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:22:39 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:22:39 -0500 Subject: [PATCH v3 4/9] davinci: McASP configuration for Omapl138-Hawkboard Message-ID: <1287076960-4435-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration for MacASP used on the Hawkboard-L138 system in order to add Audio support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:22:52 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:22:52 -0500 Subject: [PATCH v3 5/9] davinci: Audio support for Omapl138-Hawkboard Message-ID: <1287076972-4458-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 45 +++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 358944b..c0a999a 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,37 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci Hawkboard audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -134,6 +166,19 @@ static __init void omapl138_hawk_init(void) ret = omapl138_hawk_config_emac(); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("%s: i2c0 registration failed: %d\n", + __func__, ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:23:00 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:23:00 -0500 Subject: [PATCH v3 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard Message-ID: <1287076980-4481-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration to enable MMC/SD and USB-OHCI on the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 4 ++++ arch/arm/mach-davinci/include/mach/mux.h | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..646e8b2 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -548,6 +548,10 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..f2c2117 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -913,6 +913,10 @@ enum davinci_da850_index { DA850_GPIO2_15, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO3_12, + DA850_GPIO3_13, + DA850_GPIO2_4, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:23:07 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:23:07 -0500 Subject: [PATCH v3 7/9] davinci: MMC/SD support for Omapl138-Hawkboar Message-ID: <1287076987-4504-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c0a999a..723ac03 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define HAWKBOARD_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -149,6 +151,32 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -179,6 +207,28 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); + + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:23:28 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:23:28 -0500 Subject: [PATCH v3 8/9] davinci: USB clocks for Omapl138-Hawkboard Message-ID: <1287077008-4527-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB clocks for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 646e8b2..77801ed 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,21 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, + .flags = ALWAYS_ENABLED, + }; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, + }; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +402,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 12:23:38 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 12:23:38 -0500 Subject: [PATCH v3 9/9] davinci: USB-OHCI support for Omapl138-Hawkboard Message-ID: <1287077018-4550-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB-OHCI support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB pen drive In order to connect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 101 +++++++++++++++++++++++++++ 1 files changed, 101 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 723ac03..bac29fc 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -177,6 +180,94 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -229,6 +320,16 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From cyril at ti.com Thu Oct 14 13:38:44 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:44 -0400 Subject: [PATCH 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-2-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch adds a driver for this controller device. The driver does not expose a user-land interface. Protocol drivers built on top of this layer are expected to remain in-kernel. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 92 ++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 443 +++++++++++++++++++++++++++ 4 files changed, 547 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/misc/ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h new file mode 100644 index 0000000..8365101 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -0,0 +1,92 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TI_SSP_H__ +#define __TI_SSP_H__ + +struct ti_ssp_data { + unsigned long out_clock; +}; + +struct ti_ssp_port_data { + const char *ssp_dev_name; + int port; + unsigned long iosel; /* see note below */ + unsigned long config; +}; + +struct ti_ssp_port; + +/* + * Sequencer port IO pin configuration bits. These do not correlate 1-1 with + * the hardware. The iosel field in the port data combines iosel1 and iosel2, + * and is therefore not a direct map to register space. It is best to use the + * macros below to construct iosel values. + * + * least significant 16 bits --> iosel1 + * most significant 16 bits --> iosel2 + */ + +#define SSP_IN 0x0000 +#define SSP_DATA 0x0001 +#define SSP_CLOCK 0x0002 +#define SSP_CHIPSEL 0x0003 +#define SSP_OUT 0x0004 +#define SSP_PIN_SEL(pin, v) ((v) << ((pin) * 3)) +#define SSP_PIN_MASK(pin) SSP_PIN_SEL(pin, 0x7) +#define SSP_INPUT_SEL(pin) ((pin) << 16) + +/* Sequencer port config bits */ +#define SSP_EARLY_DIN BIT(8) +#define SSP_DELAY_DOUT BIT(9) + +/* Sequence map definitions */ +#define SSP_CLK_HIGH BIT(0) +#define SSP_CLK_LOW 0 +#define SSP_DATA_HIGH BIT(1) +#define SSP_DATA_LOW 0 +#define SSP_CS_HIGH BIT(2) +#define SSP_CS_LOW 0 +#define SSP_OUT_MODE BIT(3) +#define SSP_IN_MODE 0 +#define SSP_DATA_REG BIT(4) +#define SSP_ADDR_REG 0 + +#define SSP_OPCODE_DIRECT ((0x0) << 5) +#define SSP_OPCODE_TOGGLE ((0x1) << 5) +#define SSP_OPCODE_SHIFT ((0x2) << 5) +#define SSP_OPCODE_BRANCH0 ((0x4) << 5) +#define SSP_OPCODE_BRANCH1 ((0x5) << 5) +#define SSP_OPCODE_BRANCH ((0x6) << 5) +#define SSP_OPCODE_STOP ((0x7) << 5) +#define SSP_BRANCH(addr) ((addr) << 8) +#define SSP_COUNT(cycles) ((cycles) << 8) + +struct ti_ssp_port *ti_ssp_open(const struct ti_ssp_port_data *data); +int ti_ssp_close(struct ti_ssp_port *dev); +int ti_ssp_dumpregs(struct ti_ssp_port *dev); +int ti_ssp_raw_read(struct ti_ssp_port *dev); +int ti_ssp_raw_write(struct ti_ssp_port *dev, u32 val); +int ti_ssp_load(struct ti_ssp_port *dev, int offs, u32* prog, int len); +int ti_ssp_run(struct ti_ssp_port *dev, u32 pc, u32 input, u32 *output); +int ti_ssp_set_mode(struct ti_ssp_port *dev, int mode); +int ti_ssp_set_iosel(struct ti_ssp_port *dev, u32 iosel); + +#endif /* __TI_SSP_H__ */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..9fb8470 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -390,6 +390,17 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. +config TI_SSP + depends on ARCH_DAVINCI_TNETV107X + tristate "Sequencer Serial Port support" + default y + ---help--- + Say Y here if you want support for the Sequencer Serial Port + in a Texas Instruments TNETV107X SoC. + + To compile this driver as a module, choose M here: the + module will be called ti_ssp. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..7568100 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o +obj-$(CONFIG_TI_SSP) += ti_ssp.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o diff --git a/drivers/misc/ti_ssp.c b/drivers/misc/ti_ssp.c new file mode 100644 index 0000000..edbc94d --- /dev/null +++ b/drivers/misc/ti_ssp.c @@ -0,0 +1,443 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Register Offsets */ +#define SSP_REG_REV 0x00 +#define SSP_REG_IOSEL_1 0x04 +#define SSP_REG_IOSEL_2 0x08 +#define SSP_REG_PREDIV 0x0c +#define SSP_REG_INTR_STAT 0x10 +#define SSP_REG_INTR_EN 0x14 +#define SSP_REG_TEST_CTRL 0x18 + +/* Per port registers */ +#define SSP_PORT_REG_CFG_2 0x00 +#define SSP_PORT_REG_ADDR 0x04 +#define SSP_PORT_REG_DATA 0x08 +#define SSP_PORT_REG_CFG_1 0x0c +#define SSP_PORT_REG_STATE 0x10 + +#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) +#define SSP_PORT_CLKRATE_MASK 0x0f + +#define SSP_SEQRAM_WR_EN BIT(4) +#define SSP_SEQRAM_RD_EN BIT(5) +#define SSP_START BIT(15) +#define SSP_BUSY BIT(10) +#define SSP_PORT_ASL BIT(7) +#define SSP_PORT_CFO1 BIT(6) + +#define SSP_PORT_SEQRAM_SIZE 32 + +static const int ssp_port_base[] = {0x040, 0x080}; +static const int ssp_port_seqram[] = {0x100, 0x180}; + +/* Register Access Macros */ +#define ssp_read(ssp, reg) __raw_readl((ssp)->regs + SSP_REG_##reg) +#define ssp_write(ssp, reg, val) __raw_writel(val, (ssp)->regs + SSP_REG_##reg) + +#define ssp_rmw(ssp, reg, mask, bits) \ + ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~(mask)) | (bits)) + +#define ssp_port_read(ssp, port, reg) \ + __raw_readl((ssp)->regs + ssp_port_base[port] + \ + SSP_PORT_REG_##reg) + +#define ssp_port_write(ssp, port, reg, val) \ + __raw_writel(val, (ssp)->regs + ssp_port_base[port] + \ + SSP_PORT_REG_##reg) + +#define ssp_port_rmw(ssp, port, reg, mask, bits) \ + ssp_port_write(ssp, port, reg, \ + (ssp_port_read(ssp, port, reg) & ~(mask)) | (bits)) + +#define ssp_port_clr_bits(ssp, port, reg, bits) \ + ssp_port_rmw(ssp, port, reg, bits, 0) + +#define ssp_port_set_bits(ssp, port, reg, bits) \ + ssp_port_rmw(ssp, port, reg, 0, bits) + +struct ti_ssp { + struct resource *res; + void __iomem *regs; + struct timer_list timer; + struct ti_ssp_port *ports[2]; + spinlock_t lock; + struct clk *clk; + struct device *dev; +}; + +struct ti_ssp_port { + int num; + struct ti_ssp *ssp; + spinlock_t lock; +}; + +struct ti_ssp_port *ti_ssp_open(const struct ti_ssp_port_data *data) +{ + struct ti_ssp *ssp; + struct ti_ssp_port *port; + struct device *dev; + int error = 0; + + dev = bus_find_device_by_name(&platform_bus_type, NULL, + data->ssp_dev_name); + if (!dev || !dev->driver) + return ERR_PTR(-ENODEV); + + if (!get_device(dev)) + return ERR_PTR(-ENODEV); + + ssp = platform_get_drvdata(to_platform_device(dev)); + if (!ssp) { + error = -ENODEV; + goto error_put; + } + + port = kzalloc(sizeof(*port), GFP_KERNEL); + if (!port) { + error = -ENOMEM; + goto error_put; + } + + port->num = data->port; + port->ssp = ssp; + spin_lock_init(&port->lock); + + spin_lock(&ssp->lock); + + if (ssp->ports[port->num]) { + error = -EBUSY; + goto error_unlock; + } + + ssp->ports[port->num] = port; + + spin_unlock(&ssp->lock); + + ti_ssp_set_iosel(port, data->iosel); + + spin_lock(&port->lock); + ssp_port_rmw(ssp, port->num, CFG_1, SSP_PORT_CONFIG_MASK, + data->config); + ssp_port_rmw(ssp, port->num, CFG_2, SSP_PORT_CLKRATE_MASK, 0); + spin_unlock(&port->lock); + + return port; + +error_unlock: + spin_unlock(&ssp->lock); +error_put: + put_device(dev); + return ERR_PTR(error); +} +EXPORT_SYMBOL(ti_ssp_open); + +int ti_ssp_close(struct ti_ssp_port *port) +{ + if (!port || !port->ssp) + return -EINVAL; + port->ssp->ports[port->num] = NULL; + put_device(port->ssp->dev); + kfree(port); + return 0; +} +EXPORT_SYMBOL(ti_ssp_close); + +int ti_ssp_set_mode(struct ti_ssp_port *port, int mode) +{ + if (!port || !port->ssp) + return -EINVAL; + + spin_lock(&port->lock); + mode &= SSP_PORT_CONFIG_MASK; + ssp_port_rmw(port->ssp, port->num, CFG_1, SSP_PORT_CONFIG_MASK, mode); + spin_unlock(&port->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_set_mode); + +int ti_ssp_set_iosel(struct ti_ssp_port *port, u32 iosel) +{ + unsigned int val; + + if (!port || !port->ssp) + return -EINVAL; + + spin_lock(&port->lock); + + /* IOSEL1 gets the least significant 16 bits */ + val = ssp_read(port->ssp, IOSEL_1); + val &= 0xffff << (port->num ? 0 : 16); + val |= (iosel & 0xffff) << (port->num ? 16 : 0); + ssp_write(port->ssp, IOSEL_1, val); + + /* IOSEL2 gets the most significant 16 bits */ + val = ssp_read(port->ssp, IOSEL_2); + val &= 0x0007 << (port->num ? 0 : 16); + val |= (iosel & 0x00070000) >> (port->num ? 0 : 16); + ssp_write(port->ssp, IOSEL_2, val); + + spin_unlock(&port->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_set_iosel); + +int ti_ssp_load(struct ti_ssp_port *port, int offs, u32* prog, int len) +{ + int i; + + if (!port || !port->ssp) + return -EINVAL; + + if (len > SSP_PORT_SEQRAM_SIZE) + return -ENOSPC; + + spin_lock(&port->lock); + + /* Enable SeqRAM access */ + ssp_port_set_bits(port->ssp, port->num, CFG_2, SSP_SEQRAM_WR_EN); + + /* Copy code */ + for (i = 0; i < len; i++) { + __raw_writel(prog[i], port->ssp->regs + offs + 4*i + + ssp_port_seqram[port->num]); + } + + /* Disable SeqRAM access */ + ssp_port_clr_bits(port->ssp, port->num, CFG_2, SSP_SEQRAM_WR_EN); + + spin_unlock(&port->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_load); + +int ti_ssp_raw_read(struct ti_ssp_port *port) +{ + u32 val; + + if (!port || !port->ssp) + return -EINVAL; + + val = ssp_read(port->ssp, IOSEL_2); + val >>= (port->num ? 27 : 11); + + return val & 0x0f; +} +EXPORT_SYMBOL(ti_ssp_raw_read); + +int ti_ssp_raw_write(struct ti_ssp_port *port, u32 val) +{ + u32 mask; + + if (!port || !port->ssp) + return -EINVAL; + + spin_lock(&port->ssp->lock); + val &= 0x0f; + val <<= (port->num ? 22 : 6); + mask = 0x0f; + mask <<= (port->num ? 22 : 6); + ssp_rmw(port->ssp, IOSEL_2, mask, val); + spin_unlock(&port->ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_raw_write); + +int ti_ssp_run(struct ti_ssp_port *port, u32 pc, u32 input, u32 *output) +{ + struct ti_ssp *ssp; + int count; + + if (!port || !port->ssp) + return -EINVAL; + ssp = port->ssp; + + if (pc & ~(0x3f)) + return -EINVAL; + + ssp_port_write(ssp, port->num, ADDR, input >> 16); + ssp_port_write(ssp, port->num, DATA, input & 0xffff); + ssp_port_rmw(ssp, port->num, CFG_1, 0x3f, pc); + + ssp_port_set_bits(ssp, port->num, CFG_1, SSP_START); + + for (count = 10000; count; count--) { + if ((ssp_port_read(ssp, port->num, CFG_1) & SSP_BUSY) == 0) + break; + udelay(1); + } + + if (output) { + *(output) = (ssp_port_read(ssp, port->num, ADDR) << 16) | + (ssp_port_read(ssp, port->num, DATA) & 0xffff); + } + + if (!count) { + dev_err(ssp->dev, "timed out waiting for SSP operation\n"); + return -EIO; + } + + /* return stop address */ + return ssp_port_read(ssp, port->num, STATE) & 0x3f; +} +EXPORT_SYMBOL(ti_ssp_run); + +static int __devinit ti_ssp_probe(struct platform_device *pdev) +{ + static struct ti_ssp *ssp; + const struct ti_ssp_data *pdata = pdev->dev.platform_data; + int ret = 0, prediv = 0xff; + unsigned long sysclk; + struct device *dev = &pdev->dev; + + ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); + if (!ssp) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + ssp->dev = dev; + platform_set_drvdata(pdev, ssp); + + ret = -ENODEV; + ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ssp->res) { + dev_err(dev, "cannot determine register area\n"); + goto error_res; + } + + ret = -EINVAL; + if (!request_mem_region(ssp->res->start, resource_size(ssp->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + goto error_res; + } + + ret = -ENOMEM; + ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); + if (!ssp->regs) { + dev_err(dev, "cannot map register memory\n"); + goto error_map; + } + + ret = -EINVAL; + ssp->clk = clk_get(dev, NULL); + if (IS_ERR(ssp->clk)) { + dev_err(dev, "cannot claim device clock\n"); + goto error_clk; + } + + spin_lock_init(&ssp->lock); + + platform_set_drvdata(pdev, ssp); + + /* Power on and initialize SSP */ + ret = clk_enable(ssp->clk); + if (ret) + goto error_enable; + + /* Reset registers to a sensible known state */ + ssp_write(ssp, IOSEL_1, 0); + ssp_write(ssp, IOSEL_2, 0); + ssp_write(ssp, INTR_EN, 0); + ssp_write(ssp, TEST_CTRL, 0); + ssp_port_write(ssp, 0, CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 1, CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 0, CFG_2, SSP_PORT_CFO1); + ssp_port_write(ssp, 1, CFG_2, SSP_PORT_CFO1); + + sysclk = clk_get_rate(ssp->clk); + if (pdata && pdata->out_clock) + prediv = (sysclk / pdata->out_clock) - 1; + prediv = clamp(prediv, 0, 0xff); + ssp_rmw(ssp, PREDIV, 0xff, prediv); + + return 0; + +error_enable: + clk_put(ssp->clk); +error_clk: + iounmap(ssp->regs); +error_map: + release_mem_region(ssp->res->start, resource_size(ssp->res)); +error_res: + kfree(ssp); + return ret; +} + +static int __devexit ti_ssp_remove(struct platform_device *pdev) +{ + struct ti_ssp *ssp = platform_get_drvdata(pdev); + + clk_disable(ssp->clk); + clk_put(ssp->clk); + iounmap(ssp->regs); + release_mem_region(ssp->res->start, resource_size(ssp->res)); + kfree(ssp); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static struct platform_driver ti_ssp_driver = { + .probe = ti_ssp_probe, + .remove = __devexit_p(ti_ssp_remove), + .driver.name = "ti-ssp", + .driver.owner = THIS_MODULE, +}; + +static int __init ti_ssp_init(void) +{ + return platform_driver_register(&ti_ssp_driver); +} + +static void __exit ti_ssp_exit(void) +{ + platform_driver_unregister(&ti_ssp_driver); +} + +arch_initcall_sync(ti_ssp_init); +module_exit(ti_ssp_exit); + +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); +MODULE_ALIAS("platform:ti_ssp"); +MODULE_LICENSE("GPL"); -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:45 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:45 -0400 Subject: [PATCH 02/12] davinci: add tnetv107x ssp platform device In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-3-git-send-email-cyril@ti.com> This patch adds an SSP platform device definition for the tnetv107x soc family. The clock lookup entry has also been updated to match. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 25 ++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index c9a86d8..0d0522b 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -35,6 +35,7 @@ #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 +#define TNETV107X_SSP_BASE 0x08088c00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 @@ -342,6 +343,25 @@ static struct platform_device tsc_device = { .resource = tsc_resources, }; +static struct resource ssp_resources [] = { + { + .start = TNETV107X_SSP_BASE, + .end = TNETV107X_SSP_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ssp_device = { + .name = "ti-ssp", + .id = -1, + .num_resources = ARRAY_SIZE(ssp_resources), + .resource = ssp_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -367,4 +387,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) keypad_device.dev.platform_data = info->keypad_config; platform_device_register(&keypad_device); } + + if (info->ssp_config) { + ssp_device.dev.platform_data = info->ssp_config; + platform_device_register(&ssp_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 5a681d8..c1df563 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -38,12 +38,14 @@ #include #include #include +#include struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ struct matrix_keypad_platform_data *keypad_config; + struct ti_ssp_data *ssp_config; }; extern struct platform_device tnetv107x_wdt_device; diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index daeae06..fcf30e7 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -277,7 +277,7 @@ static struct clk_lookup clks[] = { CLK(NULL, "timer1", &clk_timer1), CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm), CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp), - CLK("ti-ssp.0", NULL, &clk_ssp), + CLK("ti-ssp", NULL, &clk_ssp), CLK(NULL, "clk_tdm0", &clk_tdm0), CLK(NULL, "clk_vlynq", &clk_vlynq), CLK(NULL, "clk_mcdma", &clk_mcdma), -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:43 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:43 -0400 Subject: [PATCH 00/12] tnetv107x ssp driver stack Message-ID: <1287081535-2864-1-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch series implements a driver stack that looks like the following: +--------+ | eeprom | . . . +--------+ +-----------+ +--------------+ +---------+ | regulator | . . . | i2c-gpio | | 1-wire | . . . +-----------+ +--------------+ +---------+ +----------------------+ +--------------------------------+ | ssp-spi | | ssp-gpio | +----------------------+ +--------------------------------+ +----------------------------------------------------------+ | ssp | +----------------------------------------------------------+ Cyril Chemparathy (12): misc: add driver for sequencer serial port davinci: add tnetv107x ssp platform device davinci: add ssp config for tnetv107x evm board spi: add ti-ssp spi master driver davinci: add spi devices on tnetv107x evm regulator: add driver for tps6524x regulator davinci: add tnetv107x evm regulators gpio: add ti-ssp virtual gpio driver davinci: add tnetv107x evm ti-ssp gpio device backlight: add support for tps6116x controller davinci: add tnetv107x evm backlight device davinci: add tnetv107x evm i2c eeprom device arch/arm/mach-davinci/board-tnetv107x-evm.c | 211 ++++++ arch/arm/mach-davinci/devices-tnetv107x.c | 25 + arch/arm/mach-davinci/include/mach/ti_ssp.h | 103 +++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- drivers/gpio/Kconfig | 10 + drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 234 +++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 443 +++++++++++++ drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 812 ++++++++++++++++++++++++ drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 408 ++++++++++++ drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 339 ++++++++++ 20 files changed, 2627 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/gpio/ti-ssp-gpio.c create mode 100644 drivers/misc/ti_ssp.c create mode 100644 drivers/regulator/tps6524x-regulator.c create mode 100644 drivers/spi/spi_ti_ssp.c create mode 100644 drivers/video/backlight/tps6116x.c From cyril at ti.com Thu Oct 14 13:38:46 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:46 -0400 Subject: [PATCH 03/12] davinci: add ssp config for tnetv107x evm board In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-4-git-send-email-cyril@ti.com> This patch adds SSP configuration and pin muxing info for tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 5afa8fc..c2c467b 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define EVM_MMC_WP_GPIO 21 @@ -99,6 +100,12 @@ static const short uart1_pins[] __initdata = { -1 }; +static const short ssp_pins[] __initdata = { + TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, + TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, + TNETV107X_SSP1_3, -1 +}; + static struct mtd_partition nand_partitions[] = { /* bootloader (U-Boot, etc) in first 12 sectors */ { @@ -196,17 +203,23 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static struct ti_ssp_data ssp_config = { + .out_clock = 250 * 1000, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ .keypad_config = &keypad_config, + .ssp_config = &ssp_config, }; static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); davinci_cfg_reg_list(uart1_pins); + davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); } -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:47 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:47 -0400 Subject: [PATCH 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-5-git-send-email-cyril@ti.com> This patch adds an SPI master implementation that operates on top of an underlying TI-SSP port. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 6 + drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 408 +++++++++++++++++++++++++++ 4 files changed, 421 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi_ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 8365101..532b0a3 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -32,6 +32,12 @@ struct ti_ssp_port_data { unsigned long config; }; +struct ti_ssp_spi_data { + struct ti_ssp_port_data port_data; + int num_cs; + void (*select)(int cs); +}; + struct ti_ssp_port; /* diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 91c2f4f..c1937e4 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -298,6 +298,12 @@ config SPI_STMP3XXX help SPI driver for Freescale STMP37xx/378x SoC SSP interface +config SPI_TI_SSP + tristate "TI SSP Controller SPI Driver" + depends on SPI_MASTER && TI_SSP + help + SPI master implementation using a TI sequencer serial port. + config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e9cbd18..953aba7 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c new file mode 100644 index 0000000..132684c --- /dev/null +++ b/drivers/spi/spi_ti_ssp.c @@ -0,0 +1,408 @@ +/* + * Sequencer Serial Port (SSP) based SPI master driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) + +struct ti_ssp_spi { + struct spi_master *master; + const struct ti_ssp_spi_data *pdata; + struct device *dev; + spinlock_t lock; + struct list_head msg_queue; + struct completion complete; + int shutdown:1; + struct workqueue_struct *workqueue; + struct work_struct work; + u8 mode, bpw; + int cs_active; + struct ti_ssp_port *ssp; + u32 pc_en, pc_dis, pc_wr, pc_rd; +}; + +static u32 do_read_data(struct ti_ssp_spi *hw) +{ + u32 ret; + + ti_ssp_run(hw->ssp, hw->pc_rd, 0, &ret); + return ret; +} + +static void do_write_data(struct ti_ssp_spi *hw, u32 data) +{ + ti_ssp_run(hw->ssp, hw->pc_wr, data << (32 - hw->bpw), NULL); +} + +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, + struct spi_transfer *t) +{ + int count; + + if (hw->bpw <= 8) { + u8 *rx = t->rx_buf; + const u8 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 1) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else if (hw->bpw <= 16) { + u16 *rx = t->rx_buf; + const u16 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 2) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else { + u32 *rx = t->rx_buf; + const u32 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 4) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } + + msg->actual_length += count; /* bytes transferred */ + + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, + hw->bpw, count, (count < t->len) ? " (under)": ""); + + return (count < t->len) ? -EIO : 0; /* left over data */ +} + +static void chip_select(struct ti_ssp_spi *hw, int cs_active) +{ + cs_active = !!cs_active; + if (cs_active == hw->cs_active) + return; + ti_ssp_run(hw->ssp, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); + hw->cs_active = cs_active; +} + +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) + +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) +{ + int error, idx = 0; + u32 seqram[16]; + u32 cs_en, cs_dis, clk; + u32 topbits, botbits; + + mode &= MODE_BITS; + if (mode == hw->mode && bpw == hw->bpw) + return 0; + + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; + + /* Construct instructions */ + + /* Disable Chip Select */ + hw->pc_dis = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; + + /* Enable Chip Select */ + hw->pc_en = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Reads and writes need to be split for bpw > 16 */ + topbits = (bpw > 16) ? 16 : bpw; + botbits = bpw - topbits; + + /* Write */ + hw->pc_wr = idx; + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; + if (botbits) + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Read */ + hw->pc_rd = idx; + if (botbits) + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + error = ti_ssp_load(hw->ssp, 0, seqram, idx); + if (error < 0) + return error; + + error = ti_ssp_set_mode(hw->ssp, ((mode & SPI_CPHA) ? + 0 : SSP_EARLY_DIN)); + if (error < 0) + return error; + + hw->bpw = bpw; + hw->mode = mode; + + return error; +} + +static void ti_ssp_spi_work(struct work_struct *work) +{ + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); + + spin_lock_irq(&hw->lock); + + while (!list_empty(&hw->msg_queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + int status = 0; + + m = container_of(hw->msg_queue.next, struct spi_message, + queue); + + list_del_init(&m->queue); + + spi = m->spi; + + if (hw->pdata->select) + hw->pdata->select(spi->chip_select); + + list_for_each_entry(t, &m->transfers, transfer_list) { + int bpw = spi->bits_per_word; + int xfer_status; + + if (t->bits_per_word) + bpw = t->bits_per_word; + + if (setup_xfer(hw, bpw, spi->mode) < 0) + break; + + chip_select(hw, 1); + + spin_unlock_irq(&hw->lock); + + xfer_status = do_transfer(hw, m, t); + if (xfer_status < 0) + status = xfer_status; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + spin_lock_irq(&hw->lock); + + if (t->cs_change) + chip_select(hw, 0); + } + + chip_select(hw, 0); + m->status = status; + m->complete(m->context); + } + + if (hw->shutdown) + complete(&hw->complete); + + spin_unlock_irq(&hw->lock); +} + +static int ti_ssp_spi_setup(struct spi_device *spi) +{ + if (spi->bits_per_word > 32) + return -EINVAL; + + return 0; +} + +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) +{ + struct ti_ssp_spi *hw; + struct spi_transfer *t; + unsigned long flags; + int error = 0; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + hw = spi_master_get_devdata(spi->master); + + if (list_empty(&m->transfers) || !m->complete) + return -EINVAL; + + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->len && !(t->rx_buf || t->tx_buf)) { + dev_err(&spi->dev, "invalid xfer, no buffer\n"); + return -EINVAL; + } + + if (t->len && t->rx_buf && t->tx_buf) { + dev_err(&spi->dev, "invalid xfer, full duplex\n"); + return -EINVAL; + } + + if (t->bits_per_word > 32) { + dev_err(&spi->dev, "invalid xfer width %d\n", + t->bits_per_word); + return -EINVAL; + } + } + + spin_lock_irqsave(&hw->lock, flags); + if (hw->shutdown) { + error = -ESHUTDOWN; + goto error_unlock; + } + list_add_tail(&m->queue, &hw->msg_queue); + queue_work(hw->workqueue, &hw->work); +error_unlock: + spin_unlock_irqrestore(&hw->lock, flags); + return error; +} + +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) +{ + const struct ti_ssp_spi_data *pdata; + struct ti_ssp_spi *hw; + struct spi_master *master; + struct device *dev = &pdev->dev; + int error = 0; + + pdata = dev->platform_data; + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); + if (!master) { + dev_err(dev, "cannot allocate SPI master\n"); + return -ENOMEM; + } + + hw = spi_master_get_devdata(master); + platform_set_drvdata(pdev, hw); + + hw->master = master; + hw->dev = dev; + hw->pdata = pdata; + + spin_lock_init(&hw->lock); + init_completion(&hw->complete); + INIT_LIST_HEAD(&hw->msg_queue); + INIT_WORK(&hw->work, ti_ssp_spi_work); + + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); + if (!hw->workqueue) { + error = -ENOMEM; + dev_err(dev, "work queue creation failed\n"); + goto error_wq; + } + + hw->ssp = ti_ssp_open(&hw->pdata->port_data); + if (IS_ERR(hw->ssp)) { + error = PTR_ERR(hw->ssp); + dev_err(dev, "ssp open failed (%d)\n", error); + goto error_open; + } + + master->bus_num = pdev->id; + master->num_chipselect = hw->pdata->num_cs; + master->mode_bits = MODE_BITS; + master->flags = SPI_MASTER_HALF_DUPLEX; + master->setup = ti_ssp_spi_setup; + master->transfer = ti_ssp_spi_transfer; + + error = spi_register_master(master); + if (error) { + dev_err(dev, "master registration failed\n"); + goto error_reg; + } + + return 0; + +error_reg: + ti_ssp_close(hw->ssp); +error_open: + destroy_workqueue(hw->workqueue); +error_wq: + spi_master_put(master); + return error; +} + +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) +{ + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); + int error; + + hw->shutdown = 1; + while (!list_empty(&hw->msg_queue)) { + error = wait_for_completion_interruptible(&hw->complete); + if (error < 0) { + hw->shutdown = 0; + return error; + } + } + + ti_ssp_close(hw->ssp); + destroy_workqueue(hw->workqueue); + spi_unregister_master(hw->master); + + return 0; +} + +static struct platform_driver ti_ssp_spi_driver = { + .probe = ti_ssp_spi_probe, + .remove = __devexit_p(ti_ssp_spi_remove), + .driver.name = "ti-ssp-spi", + .driver.owner = THIS_MODULE, +}; + +static int __init ti_ssp_spi_init(void) +{ + return platform_driver_register(&ti_ssp_spi_driver); +} + +static void __exit ti_ssp_spi_exit(void) +{ + platform_driver_unregister(&ti_ssp_spi_driver); +} + +subsys_initcall(ti_ssp_spi_init); +module_exit(ti_ssp_spi_exit); + +MODULE_DESCRIPTION("SSP SPI Master"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_ALIAS("platform:spi_ti_ssp"); +MODULE_LICENSE("GPL"); -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:50 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:50 -0400 Subject: [PATCH 07/12] davinci: add tnetv107x evm regulators In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-8-git-send-email-cyril@ti.com> This patch adds regulator and spi board info definitions for the tps6524x power management IC found on tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 91 +++++++++++++++++++++++++++ 1 files changed, 91 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 52378bf..2f13544 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -260,7 +263,95 @@ static struct platform_device spi_master_device = { .dev.platform_data = &spi_master_data, }; +static struct regulator_consumer_supply usb_consumers[] = { + REGULATOR_SUPPLY("vbus", "musb_hdrc.1"), +}; + +static struct regulator_consumer_supply lcd_consumers[] = { + REGULATOR_SUPPLY("vlcd", "tps6116x"), +}; + +static struct regulator_init_data regulators[] = { + { + .constraints = { + .name = "DCDC1", + .min_uV = 1000000, + .max_uV = 1000000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC2", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC3", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 4800000, + .max_uV = 4800000, + .min_uA = 400000, + .max_uA = 1500000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(usb_consumers), + .consumer_supplies = usb_consumers, + .constraints = { + .name = "USB", + .min_uV = 5000000, + .max_uV = 5000000, + .min_uA = 200000, + .max_uA = 1000000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | + REGULATOR_CHANGE_STATUS, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(lcd_consumers), + .consumer_supplies = lcd_consumers, + .constraints = { + .name = "LCD", + .min_uV = 5000000, + .max_uV = 5000000, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, +}; + static struct spi_board_info spi_info[] __initconst = { + { + .modalias = "tps6524x", + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_0, + .platform_data = regulators, + }, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:48 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:48 -0400 Subject: [PATCH 05/12] davinci: add spi devices on tnetv107x evm In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-6-git-send-email-cyril@ti.com> This patch adds definitions for spi devices on the tnetv107x evm platform. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 51 +++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index c2c467b..52378bf 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 +#define EVM_SPI_CS_GPIO 54 static int initialize_gpio(int gpio, char *desc) { @@ -215,6 +217,52 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static void spi_select_device(int cs) +{ + static int gpio; + + if (!gpio) { + int ret; + ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel"); + if (ret < 0) { + pr_err("cannot open spi chipsel gpio\n"); + gpio = -ENOSYS; + return; + } else { + gpio = EVM_SPI_CS_GPIO; + gpio_direction_output(gpio, 0); + } + } + + if (gpio < 0) + return; + + return gpio_set_value(gpio, cs ? 1 : 0); +} + +static struct ti_ssp_spi_data spi_master_data = { + .port_data = { + .ssp_dev_name = "ti-ssp", + .port = 1, + .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | + SSP_PIN_SEL(1, SSP_DATA) | + SSP_PIN_SEL(2, SSP_CHIPSEL) | + SSP_PIN_SEL(3, SSP_IN) | + SSP_INPUT_SEL(3), + }, + .num_cs = 2, + .select = spi_select_device, +}; + +static struct platform_device spi_master_device = { + .name = "ti-ssp-spi", + .id = 0, + .dev.platform_data = &spi_master_data, +}; + +static struct spi_board_info spi_info[] __initconst = { +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -222,6 +270,9 @@ static __init void tnetv107x_evm_board_init(void) davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); + + platform_device_register(&spi_master_device); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:53 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:53 -0400 Subject: [PATCH 10/12] backlight: add support for tps6116x controller In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-11-git-send-email-cyril@ti.com> TPS6116x is an EasyScale backlight controller device. This driver supports TPS6116x devices connected on a single GPIO. Signed-off-by: Cyril Chemparathy --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 339 ++++++++++++++++++++++++++++++++++++ 3 files changed, 347 insertions(+), 1 deletions(-) create mode 100644 drivers/video/backlight/tps6116x.c diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index e54a337..06e868e 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -307,6 +307,13 @@ config BACKLIGHT_PCF50633 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to enable its driver. +config BACKLIGHT_TPS6116X + tristate "TPS6116X LCD Backlight" + depends on GENERIC_GPIO + help + This driver controls the LCD backlight level for EasyScale capable + SSP connected backlight controllers. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 44c0f81..5d407c8 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -35,4 +35,4 @@ obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o - +obj-$(CONFIG_BACKLIGHT_TPS6116X)+= tps6116x.o diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c new file mode 100644 index 0000000..62c776f --- /dev/null +++ b/drivers/video/backlight/tps6116x.c @@ -0,0 +1,339 @@ +/* + * TPS6116X LCD Backlight Controller Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS6116X_MAX_INTENSITY 31 +#define TPS6116X_DEFAULT_INTENSITY 10 + +/* Easyscale timing w/ margin (usecs) */ +#define T_POWER_SETTLE 2000 +#define T_ES_DELAY 120 +#define T_ES_DETECT 280 +#define T_ES_WINDOW (1000 - T_ES_DELAY - T_ES_DETECT) +#define T_START 3 +#define T_EOS 3 +#define T_INACTIVE 3 +#define T_ACTIVE (3 * T_INACTIVE) + +#define CMD_SET 0x72 + +struct tps6116x { + struct ti_ssp_device *handle; + struct device *dev; + int gpio, gpio_initialized; + struct mutex lock; + int intensity; + int power; + struct backlight_properties props; + struct backlight_device *bl; + int suspended:1; + struct regulator *regulator; +}; + +static int __set_power(struct tps6116x *hw, int power) +{ + unsigned long flags; + int error; + + power = !!power; + if (power == hw->power) + return 0; /* nothing to do */ + + /* disabling is simple... choke power */ + if (!power) { + error = regulator_disable(hw->regulator); + goto done; + } + + /* set ctrl pin init state for easyscale detection */ + gpio_set_value(hw->gpio, 0); + + error = regulator_enable(hw->regulator); + if (error < 0) + goto done; + + udelay(T_POWER_SETTLE); + + /* + * Now that the controller is powered up, we need to put it into 1-wire + * mode. This is a timing sensitive operation, hence the irq disable. + * Ideally, this should happen rarely, and mostly at init, so disabling + * interrupts for the duration should not be a problem. + */ + local_irq_save(flags); + + gpio_set_value(hw->gpio, 1); + udelay(T_ES_DELAY); + gpio_set_value(hw->gpio, 0); + udelay(T_ES_DETECT); + gpio_set_value(hw->gpio, 1); + + local_irq_restore(flags); + +done: + if (error >= 0) + hw->power = power; + + return error; +} + +static void __write_byte(struct tps6116x *hw, u8 data) +{ + int bit; + + gpio_set_value(hw->gpio, 1); + udelay(T_START); + + for (bit = 0; bit < 8; bit++, data <<= 1) { + int val = data & 0x80; + int t_lo = val ? T_INACTIVE : T_ACTIVE; + int t_hi = val ? T_ACTIVE : T_INACTIVE; + + gpio_set_value(hw->gpio, 0); + udelay(t_lo); + gpio_set_value(hw->gpio, 1); + udelay(t_hi); + } + + gpio_set_value(hw->gpio, 0); + udelay(T_EOS); + gpio_set_value(hw->gpio, 1); +} + +static void __set_intensity(struct tps6116x *hw, int intensity) +{ + unsigned long flags; + + intensity = clamp(intensity, 0, TPS6116X_MAX_INTENSITY); + + local_irq_save(flags); + __write_byte(hw, CMD_SET); + __write_byte(hw, intensity); + local_irq_restore(flags); +} + +static int set_intensity(struct tps6116x *hw, int intensity) +{ + int error = 0; + + if (intensity == hw->intensity) + return 0; + + mutex_lock(&hw->lock); + + if (!hw->gpio_initialized) { + error = gpio_request_one(hw->gpio, GPIOF_DIR_OUT, + dev_name(hw->dev)); + if (error < 0) + goto error; + hw->gpio_initialized = 1; + } + + error = __set_power(hw, intensity ? 1 : 0); + if (error < 0) + goto error; + + if (intensity > 0) + __set_intensity(hw, intensity); + + hw->intensity = intensity; +error: + mutex_unlock(&hw->lock); + + return error; +} + +static ssize_t intensity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "%d\n", hw->intensity); + + return len; +} + +static ssize_t intensity_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + unsigned long intensity; + int error; + + error = strict_strtoul(buf, 10, &intensity); + if (error < 0) + return error; + + error = set_intensity(hw, intensity); + if (error < 0) + return error; + + return count; +} + +DEVICE_ATTR(intensity, S_IWUSR | S_IRUGO, intensity_show, intensity_store); + +static int get_brightness(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + + return hw->intensity; +} + +static int update_status(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + int intensity = bl->props.brightness; + + if (hw->suspended) + intensity = 0; + if (bl->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + return set_intensity(hw, intensity); +} + +static const struct backlight_ops tps6116x_backlight_ops = { + .get_brightness = get_brightness, + .update_status = update_status, +}; + +static int __devinit tps6116x_probe(struct platform_device *pdev) +{ + struct tps6116x *hw; + struct device *dev = &pdev->dev; + struct backlight_properties props; + int error; + + hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL); + if (!hw) { + error = -ENOMEM; + dev_err(dev, "cannot allocate driver data\n"); + goto fail0; + } + platform_set_drvdata(pdev, hw); + + memset(hw, 0, sizeof(struct tps6116x)); + hw->gpio = (int)dev->platform_data; + hw->dev = dev; + + mutex_init(&hw->lock); + + error = device_create_file(dev, &dev_attr_intensity); + if (error < 0) { + dev_err(dev, "cannot create device attributes\n"); + goto fail1; + } + + hw->regulator = regulator_get(dev, "vlcd"); + if (IS_ERR(hw->regulator)) { + error = PTR_ERR(hw->regulator); + dev_err(dev, "cannot claim regulator\n"); + goto fail2; + } + + memset(&props, 0, sizeof(props)); + props.max_brightness = TPS6116X_MAX_INTENSITY; + props.brightness = TPS6116X_DEFAULT_INTENSITY; + + hw->bl = backlight_device_register("tps6116x", hw->dev, hw, + &tps6116x_backlight_ops, &props); + if (IS_ERR(hw->bl)) { + error = PTR_ERR(hw->bl); + dev_err(dev, "backlight registration failed\n"); + goto fail3; + } + + dev_info(dev, "registered backlight controller\n"); + return 0; + +fail3: + regulator_put(hw->regulator); +fail2: + device_remove_file(dev, &dev_attr_intensity); +fail1: + kfree(hw); + platform_set_drvdata(pdev, NULL); +fail0: + return error; +} + +static int __devexit tps6116x_remove(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + + backlight_device_unregister(hw->bl); + regulator_disable(hw->regulator); + regulator_put(hw->regulator); + device_remove_file(hw->dev, &dev_attr_intensity); + kfree(hw); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int tps6116x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 1; + update_status(hw->bl); + return 0; +} + +static int tps6116x_resume(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 0; + update_status(hw->bl); + return 0; +} + +static struct platform_driver tps6116x_driver = { + .probe = tps6116x_probe, + .remove = __devexit_p(tps6116x_remove), + .suspend = tps6116x_suspend, + .resume = tps6116x_resume, + .driver.name = "tps6116x", + .driver.owner = THIS_MODULE, +}; + +static int __init tps6116x_init(void) +{ + return platform_driver_register(&tps6116x_driver); +} + +static void __exit tps6116x_exit(void) +{ + platform_driver_unregister(&tps6116x_driver); +} + +module_init(tps6116x_init); +module_exit(tps6116x_exit); + +MODULE_DESCRIPTION("SSP TPS6116X Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tps6116x"); -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:51 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:51 -0400 Subject: [PATCH 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-9-git-send-email-cyril@ti.com> This patch adds a GPIO driver based on TI's SSP device. This driver does not support GPIO-IRQs. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 5 + drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 234 +++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/ti-ssp-gpio.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 532b0a3..4392b43 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -38,6 +38,11 @@ struct ti_ssp_spi_data { void (*select)(int cs); }; +struct ti_ssp_gpio_data { + struct ti_ssp_port_data port_data; + int start; +}; + struct ti_ssp_port; /* diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..e400761 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -111,6 +111,16 @@ config GPIO_SCH This driver can also be built as a module. If so, the module will be called sch-gpio. +config GPIO_TI_SSP + tristate "TI SSP Controller GPIO Driver" + depends on GPIOLIB && TI_SSP + help + Say yes here to support a virtual GPIO interface on TI SSP ports. + Each SSP port translates into 4 GPIOs, with no IRQ support. + + This driver can also be built as a module. If so, the module + will be called ti-ssp-gpio. + comment "I2C GPIO expanders:" config GPIO_MAX7300 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..98b4551 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c new file mode 100644 index 0000000..fea4b50 --- /dev/null +++ b/drivers/gpio/ti-ssp-gpio.c @@ -0,0 +1,234 @@ +/* + * Sequencer Serial Port (SSP) based virtual GPIO driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ti_ssp_gpio { + const struct ti_ssp_gpio_data *pdata; + struct ti_ssp_port_data port_data; + struct gpio_chip chip; +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) + struct device *dev; + spinlock_t lock; + struct ti_ssp_port *ssp; + u8 out; +}; + +static int attach_ssp(struct ti_ssp_gpio *gpio) +{ + struct ti_ssp_port *ssp; + + if (gpio->ssp) + return 0; + + ssp = ti_ssp_open(&gpio->port_data); + if (IS_ERR(ssp)) + return PTR_ERR(ssp); + gpio->ssp = ssp; + + return 0; +} + +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error = 0; + + spin_lock(&gpio->lock); + + gpio->port_data.iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->port_data.iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); + + if (!gpio->ssp) + error = attach_ssp(gpio); + else + error = ti_ssp_set_iosel(gpio->ssp, gpio->port_data.iosel); + + spin_unlock(&gpio->lock); + + return error; +} + +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error; + + spin_lock(&gpio->lock); + + gpio->port_data.iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->port_data.iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); + + if (!gpio->ssp) + error = attach_ssp(gpio); + else + error = ti_ssp_set_iosel(gpio->ssp, gpio->port_data.iosel); + + if (error < 0) + goto error; + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + error = ti_ssp_raw_write(gpio->ssp, gpio->out); + +error: + spin_unlock(&gpio->lock); + return error; +} + +static int value_get(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error; + + spin_lock(&gpio->lock); + + error = attach_ssp(gpio); + if (error < 0) + goto error; + + error = ti_ssp_raw_read(gpio->ssp); + if (error >= 0) + error = (error & BIT(gpio_num)) ? 1 : 0; + +error: + spin_unlock(&gpio->lock); + return error; +} + +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + + spin_lock(&gpio->lock); + if (attach_ssp(gpio) < 0) + return; + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + ti_ssp_raw_write(gpio->ssp, gpio->out); + spin_unlock(&gpio->lock); +} + +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) +{ + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct ti_ssp_gpio *gpio; + int error; + + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(dev, "cannot allocate driver data\n"); + return -ENOMEM; + } + + gpio->dev = dev; + gpio->pdata = pdata; + gpio->port_data = pdata->port_data; + gpio->port_data.iosel = SSP_PIN_SEL(0, SSP_IN) | + SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | + SSP_PIN_SEL(3, SSP_IN); + spin_lock_init(&gpio->lock); + platform_set_drvdata(pdev, gpio); + + gpio->chip.base = gpio->pdata->start; + gpio->chip.ngpio = 4; + gpio->chip.dev = &pdev->dev; + gpio->chip.label = "ti_ssp_gpio"; + gpio->chip.owner = THIS_MODULE; + gpio->chip.get = value_get; + gpio->chip.set = value_set; + gpio->chip.direction_input = direction_in; + gpio->chip.direction_output = direction_out; + + error = gpiochip_add(&gpio->chip); + if (error < 0) { + dev_err(dev, "gpio chip registration failed (%d)\n", error); + goto error; + } + + dev_info(dev, "ssp gpio interface registered\n"); + return 0; + +error: + kfree(gpio); + return error; +} + +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) +{ + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); + int error; + + error = gpiochip_remove(&gpio->chip); + if (error < 0) + return error; + + if (gpio->ssp) + ti_ssp_close(gpio->ssp); + kfree(gpio); + + return 0; +} + +static struct platform_driver ti_ssp_gpio_driver = { + .probe = ti_ssp_gpio_probe, + .remove = __devexit_p(ti_ssp_gpio_remove), + .driver.name = "ti-ssp-gpio", + .driver.owner = THIS_MODULE, +}; + +static int __init ti_ssp_gpio_init(void) +{ + return platform_driver_register(&ti_ssp_gpio_driver); +} + +static void __exit ti_ssp_gpio_exit(void) +{ + platform_driver_unregister(&ti_ssp_gpio_driver); +} + +subsys_initcall(ti_ssp_gpio_init); +module_exit(ti_ssp_gpio_exit); + +MODULE_AUTHOR("Cyril Chemparathy "); +MODULE_DESCRIPTION("GPIO interface for Texas Instruments SSP"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti-ssp-gpio"); -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:55 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:55 -0400 Subject: [PATCH 12/12] davinci: add tnetv107x evm i2c eeprom device In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-13-git-send-email-cyril@ti.com> The tnetv107x evm board has an I2C device connected on one of the SSP ports. This patch adds board definitions for a GPIO based I2C master, as well as definitions for the eeprom device on these boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 35 +++++++++++++++++++++++---- 1 files changed, 30 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 0a1e9c8..2e3d842 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include @@ -45,6 +48,8 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_I2C_SDA_GPIO (SSP_GPIO_START + 0) +#define EVM_I2C_SCL_GPIO (SSP_GPIO_START + 1) #define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) @@ -270,11 +275,6 @@ static struct ti_ssp_gpio_data ssp_gpio_data = { .port_data = { .ssp_dev_name = "ti-ssp", .port = 0, - .iosel = SSP_PIN_SEL(0, SSP_OUT) | - SSP_PIN_SEL(1, SSP_OUT) | - SSP_PIN_SEL(2, SSP_OUT) | - SSP_PIN_SEL(3, SSP_OUT) | - SSP_INPUT_SEL(3), }, .start = SSP_GPIO_START, }; @@ -382,6 +382,29 @@ static struct platform_device backlight_device = { .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, }; +struct i2c_gpio_platform_data i2c_data = { + .sda_pin = EVM_I2C_SDA_GPIO, + .scl_pin = EVM_I2C_SCL_GPIO, +}; + +static struct platform_device i2c_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &i2c_data, +}; + +static struct at24_platform_data at24_config = { + .byte_len = SZ_16K / 8, + .page_size = 16, +}; + +static struct i2c_board_info i2c_info[] __initconst = { + { + I2C_BOARD_INFO("24c16", 0x50), + .platform_data = &at24_config, + }, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -393,8 +416,10 @@ static __init void tnetv107x_evm_board_init(void) platform_device_register(&spi_master_device); platform_device_register(&ssp_gpio_device); platform_device_register(&backlight_device); + platform_device_register(&i2c_device); spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:54 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:54 -0400 Subject: [PATCH 11/12] davinci: add tnetv107x evm backlight device In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-12-git-send-email-cyril@ti.com> The tnetv107x evm board has a backlight device that is connected on one of the SSP ports. This patch adds the board definitions necessary to plug the backlight driver to the GPIO corresponding to this SSP pin. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 7b4f86e..0a1e9c8 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -45,6 +45,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) { @@ -375,6 +376,12 @@ static struct spi_board_info spi_info[] __initconst = { }, }; +static struct platform_device backlight_device = { + .name = "tps6116x", + .id = -1, + .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -385,6 +392,7 @@ static __init void tnetv107x_evm_board_init(void) platform_device_register(&spi_master_device); platform_device_register(&ssp_gpio_device); + platform_device_register(&backlight_device); spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:52 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:52 -0400 Subject: [PATCH 09/12] davinci: add tnetv107x evm ti-ssp gpio device In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-10-git-send-email-cyril@ti.com> This patch adds definitions to hook up one of the ti-ssp ports to the SSP GPIO driver. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 2f13544..7b4f86e 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -40,6 +40,8 @@ #include #include +#define SSP_GPIO_START 128 + #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 @@ -263,6 +265,25 @@ static struct platform_device spi_master_device = { .dev.platform_data = &spi_master_data, }; +static struct ti_ssp_gpio_data ssp_gpio_data = { + .port_data = { + .ssp_dev_name = "ti-ssp", + .port = 0, + .iosel = SSP_PIN_SEL(0, SSP_OUT) | + SSP_PIN_SEL(1, SSP_OUT) | + SSP_PIN_SEL(2, SSP_OUT) | + SSP_PIN_SEL(3, SSP_OUT) | + SSP_INPUT_SEL(3), + }, + .start = SSP_GPIO_START, +}; + +static struct platform_device ssp_gpio_device = { + .name = "ti-ssp-gpio", + .id = 0, + .dev.platform_data = &ssp_gpio_data, +}; + static struct regulator_consumer_supply usb_consumers[] = { REGULATOR_SUPPLY("vbus", "musb_hdrc.1"), }; @@ -363,6 +384,8 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); platform_device_register(&spi_master_device); + platform_device_register(&ssp_gpio_device); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } -- 1.7.0.4 From cyril at ti.com Thu Oct 14 13:38:49 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 14 Oct 2010 14:38:49 -0400 Subject: [PATCH 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287081535-2864-1-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> Message-ID: <1287081535-2864-7-git-send-email-cyril@ti.com> TPS6524X provides three step-down converters and two general-purpose LDO voltage regulators. This device is interfaced using SPI. Signed-off-by: Cyril Chemparathy --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 812 ++++++++++++++++++++++++++++++++ 3 files changed, 823 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/tps6524x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 172951b..7875c2e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -235,5 +235,15 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. +config REGULATOR_TPS6524X + tristate "TI TPS6524X Power regulators" + depends on TI_SSP + help + This driver supports TPS6524X voltage regulator chips. TPS6524X + provides three step-down converters and two general-purpose LDO + voltage regulators. This device is interfaced using a customized + serial interface currently supported on the sequencer serial + port controller. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 8285fd8..a8e5bc0 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c new file mode 100644 index 0000000..03cfe57 --- /dev/null +++ b/drivers/regulator/tps6524x-regulator.c @@ -0,0 +1,812 @@ +/* + * Regulator driver for TPS6524x PMIC + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_LDO_SET 0x0 +#define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */ +#define LDO_VSEL_MASK 0x0f +#define LDO2_ILIM_SHIFT 12 +#define LDO2_VSEL_SHIFT 4 +#define LDO1_ILIM_SHIFT 8 +#define LDO1_VSEL_SHIFT 0 + +#define REG_BLOCK_EN 0x1 +#define BLOCK_MASK 1 +#define BLOCK_LDO1_SHIFT 0 +#define BLOCK_LDO2_SHIFT 1 +#define BLOCK_LCD_SHIFT 2 +#define BLOCK_USB_SHIFT 3 + +#define REG_DCDC_SET 0x2 +#define DCDC_VDCDC_MASK 0x1f +#define DCDC_VDCDC1_SHIFT 0 +#define DCDC_VDCDC2_SHIFT 5 +#define DCDC_VDCDC3_SHIFT 10 + +#define REG_DCDC_EN 0x3 +#define DCDCDCDC_EN_MASK 0x1 +#define DCDCDCDC1_EN_SHIFT 0 +#define DCDCDCDC1_PG_MSK BIT(1) +#define DCDCDCDC2_EN_SHIFT 2 +#define DCDCDCDC2_PG_MSK BIT(3) +#define DCDCDCDC3_EN_SHIFT 4 +#define DCDCDCDC3_PG_MSK BIT(5) + +#define REG_USB 0x4 +#define USB_ILIM_SHIFT 0 +#define USB_ILIM_MASK 0x3 +#define USB_TSD_SHIFT 2 +#define USB_TSD_MASK 0x3 +#define USB_TWARN_SHIFT 4 +#define USB_TWARN_MASK 0x3 +#define USB_IWARN_SD BIT(6) +#define USB_FAST_LOOP BIT(7) + +#define REG_ALARM 0x5 +#define ALARM_LDO1 BIT(0) +#define ALARM_DCDC1 BIT(1) +#define ALARM_DCDC2 BIT(2) +#define ALARM_DCDC3 BIT(3) +#define ALARM_LDO2 BIT(4) +#define ALARM_USB_WARN BIT(5) +#define ALARM_USB_ALARM BIT(6) +#define ALARM_LCD BIT(9) +#define ALARM_TEMP_WARM BIT(10) +#define ALARM_TEMP_HOT BIT(11) +#define ALARM_NRST BIT(14) +#define ALARM_POWERUP BIT(15) + +#define REG_INT_ENABLE 0x6 +#define INT_LDO1 BIT(0) +#define INT_DCDC1 BIT(1) +#define INT_DCDC2 BIT(2) +#define INT_DCDC3 BIT(3) +#define INT_LDO2 BIT(4) +#define INT_USB_WARN BIT(5) +#define INT_USB_ALARM BIT(6) +#define INT_LCD BIT(9) +#define INT_TEMP_WARM BIT(10) +#define INT_TEMP_HOT BIT(11) +#define INT_GLOBAL_EN BIT(15) + +#define REG_INT_STATUS 0x7 +#define STATUS_LDO1 BIT(0) +#define STATUS_DCDC1 BIT(1) +#define STATUS_DCDC2 BIT(2) +#define STATUS_DCDC3 BIT(3) +#define STATUS_LDO2 BIT(4) +#define STATUS_USB_WARN BIT(5) +#define STATUS_USB_ALARM BIT(6) +#define STATUS_LCD BIT(9) +#define STATUS_TEMP_WARM BIT(10) +#define STATUS_TEMP_HOT BIT(11) + +#define REG_SOFTWARE_RESET 0xb +#define REG_WRITE_ENABLE 0xd +#define REG_REV_ID 0xf + +#define N_DCDC 3 +#define N_LDO 2 +#define N_SWITCH 2 +#define N_REGULATORS (3 /* DCDC */ + \ + 2 /* LDO */ + \ + 2 /* switch */) + +#define FIXED_ILIMSEL BIT(0) +#define FIXED_VOLTAGE BIT(1) + +#define CMD_READ(reg) ((reg) << 6) +#define CMD_WRITE(reg) (BIT(5) | (reg) << 6) +#define STAT_CLK BIT(3) +#define STAT_WRITE BIT(2) +#define STAT_INVALID BIT(1) +#define STAT_WP BIT(0) + +struct field { + int reg; + int shift; + int mask; +}; + +struct supply_info { + const char *name; + int n_voltages; + const int *voltages; + int fixed_voltage; + int n_ilimsels; + const int *ilimsels; + int fixed_ilimsel; + int flags; + struct field enable, voltage, ilimsel; +}; + +struct tps6524x { + struct device *dev; + struct spi_device *spi; + struct mutex lock; + struct regulator_desc desc[N_REGULATORS]; + struct regulator_dev *rdev[N_REGULATORS]; +}; + +static int __read_reg(struct tps6524x *hw, int reg) +{ + int error = 0; + u16 cmd = CMD_READ(reg), in; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = ∈ + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "read reg %d, data %x, status %x\n", + reg, in, status); + + if (!(status & STAT_CLK) || (status & STAT_WRITE)) + return -EIO; + + if (status & STAT_INVALID) + return -EINVAL; + + return in; +} + +static int read(struct tps6524x *hw, int reg) +{ + int ret; + + mutex_lock(&hw->lock); + ret = __read_reg(hw, reg); + mutex_unlock(&hw->lock); + + return ret; +} + +static int __write_reg(struct tps6524x *hw, int reg, int val) +{ + int error = 0; + u16 cmd = CMD_WRITE(reg), out = val; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = &out; + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n", + reg, out, status); + + if (!(status & STAT_CLK) || !(status & STAT_WRITE)) + return -EIO; + + if (status & (STAT_INVALID | STAT_WP)) + return -EINVAL; + + return error; +} + +static int write(struct tps6524x *hw, int reg, int val) +{ + int ret; + + mutex_lock(&hw->lock); + ret = __write_reg(hw, reg, val); + mutex_unlock(&hw->lock); + + return ret; +} + +static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + ret = __read_reg(hw, reg); + if (ret < 0) + return ret; + + ret &= ~mask; + ret |= val; + + ret = __write_reg(hw, reg, ret); + + return (ret < 0) ? ret : 0; +} + +static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + mutex_lock(&hw->lock); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 1); + if (ret) { + dev_err(hw->dev, "failed to set write enable\n"); + goto error; + } + + ret = __rmw_reg(hw, reg, mask, val); + if (ret) + dev_err(hw->dev, "failed to rmw register %d\n", reg); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 0); + if (ret) { + dev_err(hw->dev, "failed to clear write enable\n"); + goto error; + } + +error: + mutex_unlock(&hw->lock); + + return ret; +} + +static int read_field(struct tps6524x *hw, const struct field *field) +{ + int tmp; + + tmp = read(hw, field->reg); + if (tmp < 0) + return tmp; + + return (tmp >> field->shift) & field->mask; +} + +static int write_field(struct tps6524x *hw, const struct field *field, + int val) +{ + if (val & ~field->mask) + return -EOVERFLOW; + + return rmw_protect(hw, field->reg, + field->mask << field->shift, + val << field->shift); +} + +static const int dcdc1_voltages[] = { + 800000, 825000, 850000, 875000, + 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, + 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, + 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, + 1500000, 1525000, 1550000, 1575000, +}; + +static const int dcdc2_voltages[] = { + 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, + 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, + 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, + 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, +}; + +static const int dcdc3_voltages[] = { + 2400000, 2450000, 2500000, 2550000, 2600000, + 2650000, 2700000, 2750000, 2800000, 2850000, + 2900000, 2950000, 3000000, 3050000, 3100000, + 3150000, 3200000, 3250000, 3300000, 3350000, + 3400000, 3450000, 3500000, 3550000, 3600000, +}; + +static const int ldo1_voltages[] = { + 4300000, 4350000, 4400000, 4450000, + 4500000, 4550000, 4600000, 4650000, + 4700000, 4750000, 4800000, 4850000, + 4900000, 4950000, 5000000, 5050000, +}; + +static const int ldo2_voltages[] = { + 1100000, 1150000, 1200000, 1250000, + 1300000, 1700000, 1750000, 1800000, + 1850000, 1900000, 3150000, 3200000, + 3250000, 3300000, 3350000, 3400000, +}; + +static const int ldo_ilimsel[] = { + 400000, 1500000 +}; + +static const int usb_ilimsel[] = { + 200000, 400000, 800000, 1000000 +}; + +#define __MK_FIELD(_reg, _mask, _shift) \ + { .reg = (_reg), .mask = (_mask), .shift = (_shift), } + +static const struct supply_info supply_info[N_REGULATORS] = { + { + .name = "DCDC1", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc1_voltages), + .voltages = dcdc1_voltages, + .fixed_ilimsel = 2400000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC1_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC1_SHIFT), + }, + { + .name = "DCDC2", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc2_voltages), + .voltages = dcdc2_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC2_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC2_SHIFT), + }, + { + .name = "DCDC3", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc3_voltages), + .voltages = dcdc3_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC3_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC3_SHIFT), + }, + { + .name = "LDO1", + .n_voltages = ARRAY_SIZE(ldo1_voltages), + .voltages = ldo1_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO1_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO1_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO1_ILIM_SHIFT), + }, + { + .name = "LDO2", + .n_voltages = ARRAY_SIZE(ldo2_voltages), + .voltages = ldo2_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO2_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO2_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO2_ILIM_SHIFT), + }, + { + .name = "USB", + .flags = FIXED_VOLTAGE, + .fixed_voltage = 5000000, + .n_ilimsels = ARRAY_SIZE(usb_ilimsel), + .ilimsels = usb_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_USB_SHIFT), + .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK, + USB_ILIM_SHIFT), + }, + { + .name = "LCD", + .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, + .fixed_voltage = 5000000, + .fixed_ilimsel = 400000, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LCD_SHIFT), + }, +}; + +static int list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return selector ? -EINVAL : info->fixed_voltage; + else + return (selector < 0 || selector >= info->n_voltages) ? + -EINVAL : info->voltages[selector]; +} + +static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return -EINVAL; + + for (i = 0; i < info->n_voltages; i++) + if (min_uV <= info->voltages[i] && + max_uV >= info->voltages[i]) + break; + + if (i >= info->n_voltages) + return -EINVAL; + + return write_field(hw, &info->voltage, i); +} + +static int get_voltage(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return info->fixed_voltage; + + ret = read_field(hw, &info->voltage); + if (ret < 0) + return ret; + if (ret >= info->n_voltages) + return -EINVAL; + return info->voltages[ret]; +} + +static int set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return -EINVAL; + + for (i = 0; i < info->n_ilimsels; i++) + if (min_uA <= info->ilimsels[i] && + max_uA >= info->ilimsels[i]) + break; + + if (i >= info->n_ilimsels) + return -EINVAL; + + return write_field(hw, &info->ilimsel, i); +} + +static int get_current_limit(struct regulator_dev *rdev) +{ + struct tps6524x *hw; + const struct supply_info *info; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return info->fixed_ilimsel; + + ret = read_field(hw, &info->ilimsel); + if (ret < 0) + return ret; + if (ret >= info->n_ilimsels) + return -EINVAL; + return info->ilimsels[ret]; +} + +static int enable_supply(struct regulator_dev *rdev) +{ + struct tps6524x *hw; + const struct supply_info *info; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 1); +} + +static int disable_supply(struct regulator_dev *rdev) +{ + struct tps6524x *hw; + const struct supply_info *info; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 0); +} + +static int is_supply_enabled(struct regulator_dev *rdev) +{ + struct tps6524x *hw; + const struct supply_info *info; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return read_field(hw, &info->enable); +} + +static struct regulator_ops regulator_ops = { + .is_enabled = is_supply_enabled, + .enable = enable_supply, + .disable = disable_supply, + .get_voltage = get_voltage, + .set_voltage = set_voltage, + .list_voltage = list_voltage, + .set_current_limit = set_current_limit, + .get_current_limit = get_current_limit, +}; + +struct reg_map { + struct device_attribute *attr; + int reg; +}; + +static ssize_t show_reg(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t store_reg(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size); + +static DEVICE_ATTR(ldo_set, 0664, show_reg, store_reg); +static DEVICE_ATTR(block_en, 0664, show_reg, store_reg); +static DEVICE_ATTR(dcdc_set, 0664, show_reg, store_reg); +static DEVICE_ATTR(dcdc_en, 0664, show_reg, store_reg); +static DEVICE_ATTR(usb, 0664, show_reg, store_reg); +static DEVICE_ATTR(alarm, 0664, show_reg, store_reg); +static DEVICE_ATTR(int_enable, 0664, show_reg, store_reg); +static DEVICE_ATTR(int_status, 0664, show_reg, store_reg); +static DEVICE_ATTR(rev_id, 0664, show_reg, store_reg); +static DEVICE_ATTR(write_enable, 0664, show_reg, store_reg); +static DEVICE_ATTR(software_reset, 0664, show_reg, store_reg); + +static struct attribute *regs[] = { + &dev_attr_ldo_set.attr, + &dev_attr_block_en.attr, + &dev_attr_dcdc_set.attr, + &dev_attr_dcdc_en.attr, + &dev_attr_usb.attr, + &dev_attr_alarm.attr, + &dev_attr_int_enable.attr, + &dev_attr_int_status.attr, + &dev_attr_software_reset.attr, + &dev_attr_write_enable.attr, + &dev_attr_rev_id.attr, + NULL, +}; + +static struct reg_map reg_map[] = { + {&dev_attr_ldo_set, REG_LDO_SET }, + {&dev_attr_block_en, REG_BLOCK_EN }, + {&dev_attr_dcdc_set, REG_DCDC_SET }, + {&dev_attr_dcdc_en, REG_DCDC_EN }, + {&dev_attr_usb, REG_USB }, + {&dev_attr_alarm, REG_ALARM }, + {&dev_attr_int_enable, REG_INT_ENABLE }, + {&dev_attr_int_status, REG_INT_STATUS }, + {&dev_attr_software_reset, REG_SOFTWARE_RESET }, + {&dev_attr_write_enable, REG_WRITE_ENABLE }, + {&dev_attr_rev_id, REG_REV_ID }, + {NULL, -1}, +}; + +static int reg_addr(struct device_attribute *attr) +{ + int i; + + for (i = 0; reg_map[i].attr; i++) { + if (reg_map[i].attr == attr) + return reg_map[i].reg; + } + return -EINVAL; +} + +static ssize_t show_reg(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int r, ret; + struct tps6524x *hw = dev_get_drvdata(dev); + + BUG_ON(!hw); + + r = reg_addr(attr); + if (r < 0) + return r; + + ret = snprintf(buf, PAGE_SIZE, "%08x\n", read(hw, r)); + + return ret; +} + +static ssize_t store_reg(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int r, v; + struct tps6524x *hw = dev_get_drvdata(dev); + + BUG_ON(!hw); + + r = reg_addr(attr); + if (r < 0) + return r; + + if (sscanf(buf, "%d", &v) != 1) + return -EINVAL; + + r = write(hw, r, v); + + if (r < 0) + return r; + + return size; +} + +static const struct attribute_group registers = { + .name = "registers", + .attrs = regs, +}; + +static int __devexit pmic_remove(struct spi_device *spi) +{ + struct tps6524x *hw = spi_get_drvdata(spi); + int i; + + if (!hw) + return 0; + for (i = 0; i < N_REGULATORS; i++) { + if (!hw->rdev[i]) + continue; + regulator_unregister(hw->rdev[i]); + hw->rdev[i] = NULL; + } + sysfs_remove_group(&hw->dev->kobj, ®isters); + spi_set_drvdata(spi, NULL); + kfree(hw); + return 0; +} + +static int __devinit pmic_probe(struct spi_device *spi) +{ + struct tps6524x *hw; + struct device *dev = &spi->dev; + const struct supply_info *info = supply_info; + struct regulator_init_data *init_data; + int ret = 0, i; + + init_data = dev->platform_data; + if (!init_data) { + dev_err(dev, "could not find regulator platform data\n"); + return -EIO; + } + + hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); + if (!hw) { + dev_err(dev, "cannot allocate regulator private data\n"); + return -ENOMEM; + } + spi_set_drvdata(spi, hw); + + memset(hw, 0, sizeof(struct tps6524x)); + hw->dev = dev; + hw->spi = spi_dev_get(spi); + mutex_init(&hw->lock); + + ret = sysfs_create_group(&dev->kobj, ®isters); + if (ret) + dev_err(dev, "failed to create sysfs entries\n"); + + for (i = 0; i < N_REGULATORS; i++, info++, init_data++) { + hw->desc[i].name = info->name; + hw->desc[i].id = i; + hw->desc[i].n_voltages = info->n_voltages; + hw->desc[i].ops = ®ulator_ops; + hw->desc[i].type = REGULATOR_VOLTAGE; + hw->desc[i].owner = THIS_MODULE; + + if (info->flags & FIXED_VOLTAGE) + hw->desc[i].n_voltages = 1; + + hw->rdev[i] = regulator_register(&hw->desc[i], dev, + init_data, hw); + if (IS_ERR(hw->rdev[i])) { + ret = PTR_ERR(hw->rdev[i]); + hw->rdev[i] = NULL; + goto fail; + } + } + + return 0; + +fail: + pmic_remove(spi); + return ret; +} + +static struct spi_driver pmic_driver = { + .probe = pmic_probe, + .remove = __devexit_p(pmic_remove), + .driver.name = "tps6524x", + .driver.owner = THIS_MODULE, +}; + +static int __init pmic_driver_init(void) +{ + return spi_register_driver(&pmic_driver); +} + +static void __exit pmic_driver_exit(void) +{ + spi_unregister_driver(&pmic_driver); +} + +subsys_initcall_sync(pmic_driver_init); +module_exit(pmic_driver_exit); + +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_DESCRIPTION("TPS6524X PMIC Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:tps6524x"); -- 1.7.0.4 From sshtylyov at mvista.com Thu Oct 14 12:16:05 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 14 Oct 2010 21:16:05 +0400 Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> References: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB73AD5.2060907@mvista.com> Hello. On 10/14/10 21:21, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds EMAC support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ > 1 files changed, 49 insertions(+), 0 deletions(-) > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..3ae5178 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,53 @@ > > #include > #include > +#include > + > +#define HAWKBOARD_PHY_ID "0:07" > + > +static short omapl138_hawk_mii_pins[] __initdata = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 > +}; > + > +static int __init omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfgchip3; > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info =&davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return 0; > + > + cfgchip3 = DA8XSYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); Could be initializer... > + val = __raw_readl(cfgchip3); > + > + val &= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + pr_info("EMAC: MII PHY configured\n"); I think this pr_info() should follow __raw_writel() call. > + if (ret) > + pr_warning("%s: " > + "cpgmac/mii mux setup failed: %d\n", __func__, ret); You should return here. > + > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfgchip3); > + > + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; > + > + ret = da8xx_register_emac(); > + if (ret) > + pr_warning("%s: " > + "emac registration failed: %d\n", __func__, ret); > + return 0; Why this function returns anything at all if it'a always 0, and the result is ignored? > @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + ret = omapl138_hawk_config_emac(); Why assign 'ret', if you're ignoring the result? > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " WBR, Sergei From sshtylyov at mvista.com Thu Oct 14 12:33:36 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 14 Oct 2010 21:33:36 +0400 Subject: [PATCH v3 2/9] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1287076906-4388-1-git-send-email-vm.rod25@gmail.com> References: <1287076906-4388-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB73EF0.2010900@mvista.com> On 10/14/10 21:21, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds EDMA support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 3ae5178..358944b 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -77,6 +127,11 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + ret = da850_register_edma(da850_edma_rsv); > + if (ret) > + pr_warning("omapl138_hawk_init: " > + "edma registration failed: %d\n", ret); pr_warning("%s: EDMA registration failed: %d\n", __func__, ret); WBR, Sergei From sshtylyov at mvista.com Thu Oct 14 12:36:19 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 14 Oct 2010 21:36:19 +0400 Subject: [PATCH v3 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard In-Reply-To: <1287076980-4481-1-git-send-email-vm.rod25@gmail.com> References: <1287076980-4481-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB73F93.6010301@mvista.com> On 10/14/10 21:23, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch defines Pin Mux configuration to enable MMC/SD > and USB-OHCI on the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h > index de11aac..f2c2117 100644 > --- a/arch/arm/mach-davinci/include/mach/mux.h > +++ b/arch/arm/mach-davinci/include/mach/mux.h > @@ -913,6 +913,10 @@ enum davinci_da850_index { > DA850_GPIO2_15, > DA850_GPIO4_0, > DA850_GPIO4_1, > + DA850_GPIO3_12, > + DA850_GPIO3_13, > + DA850_GPIO2_4, > + DA850_GPIO6_13, I think these should better go in the alphabetic order. > DA850_RTC_ALARM, > }; > WBR, Sergei From sshtylyov at mvista.com Thu Oct 14 12:47:22 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 14 Oct 2010 21:47:22 +0400 Subject: [PATCH v3 9/9] davinci: USB-OHCI support for Omapl138-Hawkboard In-Reply-To: <1287077018-4550-1-git-send-email-vm.rod25@gmail.com> References: <1287077018-4550-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB7422A.6020904@mvista.com> On 10/14/10 21:23, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds USB-OHCI support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [,,,] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 723ac03..bac29fc 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -177,6 +180,94 @@ static struct davinci_mmc_config da850_mmc_config = { [...] > +static __init void omapl138_hawk_usb_init(void) > +{ > + int ret; > + u32 cfgchip2; Empty line is needed here... > + /* > + * Setup the Ref. clock frequency for the HAWK at 24 MHz. > + */ > + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + cfgchip2&= ~CFGCHIP2_REFFREQ; > + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; > + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + > + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); > + if (ret) { > + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " > + "power control: %d\n", __func__, ret); > + return; > + } > + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); > + > + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); > + if (ret) { > + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " > + "over-current indicator: %d\n", __func__, ret); > + return; > + } > + gpio_direction_input(DA850_USB1_OC_PIN); > +} > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; > @@ -229,6 +320,16 @@ static __init void omapl138_hawk_init(void) > pr_warning("%s: MMC/SD0 registration failed: %d\n", > __func__, ret); > > + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); > + if (ret) > + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", > + __func__, ret); Why are you requesting pins outside omapl138_hawk_usb_init() I wonder? > + omapl138_hawk_usb_init(); > + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); > + if (ret) > + pr_warning("%s: USB 1.1 registration failed: %d\n", > + __func__, ret); Same question... WBR, Sergei From sshtylyov at mvista.com Thu Oct 14 13:10:16 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 14 Oct 2010 22:10:16 +0400 Subject: [PATCH v2 08/10] davinci: USB1.1 clocks for Omapl138-Hawkboard In-Reply-To: <1286855840-31902-1-git-send-email-vm.rod25@gmail.com> References: <1286855840-31902-1-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB74788.3040704@mvista.com> Hello. On 10/12/10 07:57, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds USB1.1 clocks for the Hawkboard-L138 system It adds not only USB 1.1 clock but also USB 2.0 clock. > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 7787f5a..12afb25 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -345,6 +345,21 @@ static struct clk aemif_clk = { > .flags = ALWAYS_ENABLED, > }; > > +static struct clk usb11_clk = { > + .name = "usb11", > + .parent = &pll0_sysclk4, > + .lpsc = DA8XX_LPSC1_USB11, > + .gpsc = 1, > + .flags = ALWAYS_ENABLED, Why it's always enabled? WBR, Sergei From luna.id at gmail.com Thu Oct 14 15:41:48 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Thu, 14 Oct 2010 16:41:48 -0400 Subject: Problem with UART1 on Davinci with OMAP-L138 ? Message-ID: Hi, I'm trying to communication with UART1 on OMAP-L138. At the moment, I can write message to the serial port but I cannot read some. I got the error 11: Resource temporarily unavailable. To activate the UART1, I commented one line (see below) in board-da850-evm.c. I wonder what is "too much work in irq53", is it has anything to do with my problem? Is it a know bug to not be able to read from UART1 under Davinci? /* * shut down uart 0 and 1; they are not used on the board and * accessing them causes endless "too much work in irq53" messages * with arago fs */ *//__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30);* __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); Thanks for support. Regards, Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Thu Oct 14 15:53:00 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 14 Oct 2010 15:53:00 -0500 Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: On Thu, Oct 14, 2010 at 3:41 PM, Nicolas Luna wrote: > Hi, > I'm trying to communication with UART1 on OMAP-L138. At the moment, I can > write message to the serial port but I cannot read some. I got the?error 11: > Resource temporarily unavailable. > To activate the UART1, I commented one line (see below) in > board-da850-evm.c. I wonder what is "too much work in irq53", is it has > anything to do with my problem? Is it a know bug to not be able to read from > UART1 under Davinci? > /* > * shut down uart 0 and 1; they are not used on the board and > * accessing them causes endless "too much work in irq53" messages > * with arago fs > */ > //__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); > __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); Check with latest file system from angstrom I had the same problem with the initial support fro Hawkboard omapl 138 Regards Victor Rodriguez > Thanks for support. > Regards, > Nicolas > > > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > From broonie at opensource.wolfsonmicro.com Thu Oct 14 16:03:24 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Thu, 14 Oct 2010 22:03:24 +0100 Subject: [PATCH 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287081535-2864-7-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-7-git-send-email-cyril@ti.com> Message-ID: <20101014210323.GB14479@opensource.wolfsonmicro.com> On Thu, Oct 14, 2010 at 02:38:49PM -0400, Cyril Chemparathy wrote: > TPS6524X provides three step-down converters and two general-purpose LDO > voltage regulators. This device is interfaced using SPI. > > Signed-off-by: Cyril Chemparathy This looks mostly good but... > +static int read(struct tps6524x *hw, int reg) > +{ I suspect you may run into a namespace issue with this in the future. > +static const int dcdc1_voltages[] = { > + 800000, 825000, 850000, 875000, > + 900000, 925000, 950000, 975000, > + 1000000, 1025000, 1050000, 1075000, > + 1100000, 1125000, 1150000, 1175000, > + 1200000, 1225000, 1250000, 1275000, > + 1300000, 1325000, 1350000, 1375000, > + 1400000, 1425000, 1450000, 1475000, > + 1500000, 1525000, 1550000, 1575000, Looks like you could just do the maths for most of these tables, might be a bit clearer/simpler? Not a major issue either way, though. > +static int list_voltage(struct regulator_dev *rdev, unsigned selector) > +{ > + const struct supply_info *info; > + struct tps6524x *hw; > + > + hw = rdev_get_drvdata(rdev); > + info = &supply_info[rdev_get_id(rdev)]; > + > + if (info->flags & FIXED_VOLTAGE) > + return selector ? -EINVAL : info->fixed_voltage; > + else > + return (selector < 0 || selector >= info->n_voltages) ? > + -EINVAL : info->voltages[selector]; I'm not sure the ternery operator is helping legibility here - if statements might be more legible. > + ret = read_field(hw, &info->voltage); > + if (ret < 0) > + return ret; > + if (ret >= info->n_voltages) > + return -EINVAL; Shouldn't this be warning somehow - if we can't understand the register setting that'd be a driver bug, -EINVAL makes it sound like an invalid parameter was supplied. Similarly for the current limit. > +static ssize_t show_reg(struct device *dev, struct device_attribute *attr, > + char *buf); > +static ssize_t store_reg(struct device *dev, struct device_attribute *attr, > + const char *buf, size_t size); > + > +static DEVICE_ATTR(ldo_set, 0664, show_reg, store_reg); > +static DEVICE_ATTR(block_en, 0664, show_reg, store_reg); > +static DEVICE_ATTR(dcdc_set, 0664, show_reg, store_reg); > +static DEVICE_ATTR(dcdc_en, 0664, show_reg, store_reg); > +static DEVICE_ATTR(usb, 0664, show_reg, store_reg); > +static DEVICE_ATTR(alarm, 0664, show_reg, store_reg); > +static DEVICE_ATTR(int_enable, 0664, show_reg, store_reg); > +static DEVICE_ATTR(int_status, 0664, show_reg, store_reg); > +static DEVICE_ATTR(rev_id, 0664, show_reg, store_reg); > +static DEVICE_ATTR(write_enable, 0664, show_reg, store_reg); > +static DEVICE_ATTR(software_reset, 0664, show_reg, store_reg); Large chunks of this looks like it's exporting functionality which is part of the regulator API to userspace, replicating functionality which the API provides. Please either remove or replace with standard functionality. The USB setting should be integrated with the USB subsystem, assuming it's changing a USB current limit. > + init_data = dev->platform_data; > + if (!init_data) { > + dev_err(dev, "could not find regulator platform data\n"); > + return -EIO; > + } EIO doesn't look right here... From broonie at opensource.wolfsonmicro.com Thu Oct 14 16:05:16 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Thu, 14 Oct 2010 22:05:16 +0100 Subject: [PATCH 07/12] davinci: add tnetv107x evm regulators In-Reply-To: <1287081535-2864-8-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-8-git-send-email-cyril@ti.com> Message-ID: <20101014210516.GC14479@opensource.wolfsonmicro.com> On Thu, Oct 14, 2010 at 02:38:50PM -0400, Cyril Chemparathy wrote: > + { > + .num_consumer_supplies = ARRAY_SIZE(usb_consumers), > + .consumer_supplies = usb_consumers, > + .constraints = { > + .name = "USB", > + .min_uV = 5000000, > + .max_uV = 5000000, > + .min_uA = 200000, > + .max_uA = 1000000, Are you *sure* about the min_uA here - what would be the goal of enforcing a minimum current draw? For a voltage regulator current limit usually only an upper limit would be specified. The same applies to several other machine drivers in the series. From luna.id at gmail.com Thu Oct 14 16:10:53 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Thu, 14 Oct 2010 17:10:53 -0400 Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: Victor, What should I check? You mean the file system /dev/ttyS.. is not correct? Regards, Nicolas On Thu, Oct 14, 2010 at 4:53 PM, Victor Rodriguez wrote: > On Thu, Oct 14, 2010 at 3:41 PM, Nicolas Luna wrote: > > Hi, > > I'm trying to communication with UART1 on OMAP-L138. At the moment, I can > > write message to the serial port but I cannot read some. I got the error > 11: > > Resource temporarily unavailable. > > To activate the UART1, I commented one line (see below) in > > board-da850-evm.c. I wonder what is "too much work in irq53", is it has > > anything to do with my problem? Is it a know bug to not be able to read > from > > UART1 under Davinci? > > /* > > * shut down uart 0 and 1; they are not used on the board and > > * accessing them causes endless "too much work in irq53" messages > > * with arago fs > > */ > > //__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); > > __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); > > > Check with latest file system from angstrom I had the same problem > with the initial support fro Hawkboard omapl 138 > > Regards > > Victor Rodriguez > > > Thanks for support. > > Regards, > > Nicolas > > > > > > > > _______________________________________________ > > Davinci-linux-open-source mailing list > > Davinci-linux-open-source at linux.davincidsp.com > > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Thu Oct 14 16:18:23 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 14 Oct 2010 16:18:23 -0500 Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: On Thu, Oct 14, 2010 at 4:10 PM, Nicolas Luna wrote: > Victor, > What should I check? You mean the file system /dev/ttyS.. is not correct? > Regards, > Nicolas Do not top post :) > > On Thu, Oct 14, 2010 at 4:53 PM, Victor Rodriguez > wrote: >> >> On Thu, Oct 14, 2010 at 3:41 PM, Nicolas Luna wrote: >> > Hi, >> > I'm trying to communication with UART1 on OMAP-L138. At the moment, I >> > can >> > write message to the serial port but I cannot read some. I got the?error >> > 11: >> > Resource temporarily unavailable. >> > To activate the UART1, I commented one line (see below) in >> > board-da850-evm.c. I wonder what is "too much work in irq53", is it has >> > anything to do with my problem? Is it a know bug to not be able to read >> > from >> > UART1 under Davinci? >> > /* >> > * shut down uart 0 and 1; they are not used on the board and >> > * accessing them causes endless "too much work in irq53" messages >> > * with arago fs >> > */ >> > //__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); >> > __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); >> >> >> Check with latest file system from angstrom I had the same problem >> with the initial support fro Hawkboard omapl 138 Check this commit https://mail.sasken.com/OWA/redir.aspx?C=ded1d3bc21834b138e93aa6e04f85155&URL=http%3a%2f%2fgit.kernel.org%2f%3fp%3dlinux%2fkernel%2fgit%2fkhilman%2flinux-davinci.git%3ba%3dcommitdiff%3bh%3d6c18c91b3a6db6169998b54df12c9d53e74999f3 This patch adds initial support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Information on these system may be found at http://www.hawkboard.org. Basic support for the UART console is included in this patch. It's tested with latest Angstrom File Systems like ramdisk from http://alturl.com/imb45. Some old file systems used to open all the Serial Ports but in OMAP l138 the uart 1 is multiplexed and generate the spurious interrupt Try with latest Argo File Systems Regards Victor Rodriguez >> Regards >> >> Victor Rodriguez >> >> > Thanks for support. >> > Regards, >> > Nicolas >> > >> > >> > >> > _______________________________________________ >> > Davinci-linux-open-source mailing list >> > Davinci-linux-open-source at linux.davincidsp.com >> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source >> > >> > > > From vm.rod25 at gmail.com Thu Oct 14 16:44:08 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 14 Oct 2010 16:44:08 -0500 Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <4CB73AD5.2060907@mvista.com> References: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> <4CB73AD5.2060907@mvista.com> Message-ID: On Thu, Oct 14, 2010 at 12:16 PM, Sergei Shtylyov wrote: > Hello. > > On 10/14/10 21:21, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds EMAC support for the Hawkboard-L138 system > >> Signed-off-by: Victor Rodriguez >> --- >> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 49 >> +++++++++++++++++++++++++++ >> ?1 files changed, 49 insertions(+), 0 deletions(-) > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index c472dd8..3ae5178 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -19,6 +19,53 @@ >> >> ?#include >> ?#include >> +#include >> + >> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? ? "0:07" >> + >> +static short omapl138_hawk_mii_pins[] __initdata = { >> + ? ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >> + ? ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >> + ? ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >> + ? ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >> + ? ? ? DA850_MDIO_D, >> + ? ? ? -1 >> +}; >> + >> +static int __init omapl138_hawk_config_emac(void) >> +{ >> + ? ? ? void __iomem *cfgchip3; >> + ? ? ? int ret; >> + ? ? ? u32 val; >> + ? ? ? struct davinci_soc_info *soc_info =&davinci_soc_info; >> + >> + ? ? ? if (!machine_is_omapl138_hawkboard()) >> + ? ? ? ? ? ? ? return 0; >> + >> + ? ? ? cfgchip3 = DA8XSYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > > ? Could be initializer... I do not understand this >> + ? ? ? val = __raw_readl(cfgchip3); >> + >> + ? ? ? val &= ~BIT(8); >> + ? ? ? ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); >> + ? ? ? pr_info("EMAC: MII PHY configured\n"); > > ? I think this pr_info() should follow __raw_writel() call. Ok >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: " >> + ? ? ? ? ? ? ? ? ? ? ? "cpgmac/mii mux setup failed: %d\n", __func__, >> ret); > > ? You should return here. > >> + >> + ? ? ? /* configure the CFGCHIP3 register for MII */ >> + ? ? ? __raw_writel(val, cfgchip3); >> + >> + ? ? ? soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; >> + >> + ? ? ? ret = da8xx_register_emac(); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: " >> + ? ? ? ? ? ? ? ? ? ? ? "emac registration failed: %d\n", __func__, ret); >> + ? ? ? return 0; > > ? Why this function returns anything at all if it'a always 0, and the result > is ignored? > >> @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) >> >> ? ? ? ?davinci_serial_init(&omapl138_hawk_uart_config); >> >> + ? ? ? ret = omapl138_hawk_config_emac(); > > ? Why assign 'ret', if you're ignoring the result? Sorry my mistake I forgot to check this, please check the nest patch maybe it is a better implementation --- arch/arm/mach-davinci/board-omapl138-hawk.c | 49 +++++++++++++++++++++++++++ 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..35bcea1 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,53 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static __init void omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return; + + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + if (ret) + pr_warning("%s: " + "cpgmac/mii mux setup failed: %d\n", __func__, ret); + return; + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + pr_info("EMAC: MII PHY configured\n"); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: " + "emac registration failed: %d\n", __func__, ret); + return; +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 Thanks for all Regards Victor Rodriguez >> + >> ? ? ? ?ret = da8xx_register_watchdog(); >> ? ? ? ?if (ret) >> ? ? ? ? ? ? ? ?pr_warning("omapl138_hawk_init: " > > WBR, Sergei > From luna.id at gmail.com Thu Oct 14 17:27:03 2010 From: luna.id at gmail.com (Nicolas Luna) Date: Thu, 14 Oct 2010 18:27:03 -0400 Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: On Thu, Oct 14, 2010 at 5:18 PM, Victor Rodriguez wrote: > On Thu, Oct 14, 2010 at 4:10 PM, Nicolas Luna wrote: > > Victor, > > What should I check? You mean the file system /dev/ttyS.. is not correct? > > Regards, > > Nicolas > > > Do not top post :) > > > > > On Thu, Oct 14, 2010 at 4:53 PM, Victor Rodriguez > > wrote: > >> > >> On Thu, Oct 14, 2010 at 3:41 PM, Nicolas Luna > wrote: > >> > Hi, > >> > I'm trying to communication with UART1 on OMAP-L138. At the moment, I > >> > can > >> > write message to the serial port but I cannot read some. I got > the error > >> > 11: > >> > Resource temporarily unavailable. > >> > To activate the UART1, I commented one line (see below) in > >> > board-da850-evm.c. I wonder what is "too much work in irq53", is it > has > >> > anything to do with my problem? Is it a know bug to not be able to > read > >> > from > >> > UART1 under Davinci? > >> > /* > >> > * shut down uart 0 and 1; they are not used on the board and > >> > * accessing them causes endless "too much work in irq53" messages > >> > * with arago fs > >> > */ > >> > //__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); > >> > __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); > >> > >> > >> Check with latest file system from angstrom I had the same problem > >> with the initial support fro Hawkboard omapl 138 > > Check this commit > > > https://mail.sasken.com/OWA/redir.aspx?C=ded1d3bc21834b138e93aa6e04f85155&URL=http%3a%2f%2fgit.kernel.org%2f%3fp%3dlinux%2fkernel%2fgit%2fkhilman%2flinux-davinci.git%3ba%3dcommitdiff%3bh%3d6c18c91b3a6db6169998b54df12c9d53e74999f3 > > This patch adds initial support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > Information on these system may be found at http://www.hawkboard.org. > Basic support for the UART console is included in this patch. > It's tested with latest Angstrom File Systems like ramdisk > from http://alturl.com/imb45. > > > Some old file systems used to open all the Serial Ports but in OMAP > l138 the uart 1 is multiplexed and generate the spurious interrupt Try > with latest Argo File Systems > > > Regards > > Victor Rodriguez > > > >> Regards > >> > >> Victor Rodriguez > >> > >> > Thanks for support. > >> > Regards, > >> > Nicolas > >> > > >> > > >> > > >> > _______________________________________________ > >> > Davinci-linux-open-source mailing list > >> > Davinci-linux-open-source at linux.davincidsp.com > >> > > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > >> > > >> > > > > > > Victor, Sorry for top post, gmail automaticlly top post. I tried the file system with my current kernel image and I got the same error. Then I tried the linux image provided into the tar generated by the siteweb but I am not able to boot it because I need an other JTAG ID that the default one because of my silicon revision. I checked to the patch and I got the same configuration. Do you have any idea what I should change into my kernel source code to solve the uart issue? Thank you Nicolas -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Thu Oct 14 17:50:57 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 14 Oct 2010 17:50:57 -0500 Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: On Thu, Oct 14, 2010 at 5:27 PM, Nicolas Luna wrote: > > On Thu, Oct 14, 2010 at 5:18 PM, Victor Rodriguez > wrote: >> >> On Thu, Oct 14, 2010 at 4:10 PM, Nicolas Luna wrote: >> > Victor, >> > What should I check? You mean the file system /dev/ttyS.. is not >> > correct? >> > Regards, >> > Nicolas >> >> >> Do not top post :) >> >> > >> > On Thu, Oct 14, 2010 at 4:53 PM, Victor Rodriguez >> > wrote: >> >> >> >> On Thu, Oct 14, 2010 at 3:41 PM, Nicolas Luna >> >> wrote: >> >> > Hi, >> >> > I'm trying to communication with UART1 on OMAP-L138. At the moment, I >> >> > can >> >> > write message to the serial port but I cannot read some. I got >> >> > the?error >> >> > 11: >> >> > Resource temporarily unavailable. >> >> > To activate the UART1, I commented one line (see below) in >> >> > board-da850-evm.c. I wonder what is "too much work in irq53", is it >> >> > has >> >> > anything to do with my problem? Is it a know bug to not be able to >> >> > read >> >> > from >> >> > UART1 under Davinci? >> >> > /* >> >> > * shut down uart 0 and 1; they are not used on the board and >> >> > * accessing them causes endless "too much work in irq53" messages >> >> > * with arago fs >> >> > */ >> >> > //__raw_writel(0, IO_ADDRESS(DA8XX_UART1_BASE) + 0x30); >> >> > __raw_writel(0, IO_ADDRESS(DA8XX_UART0_BASE) + 0x30); >> >> >> >> >> >> Check with latest file system from angstrom I had the same problem >> >> with the initial support fro Hawkboard omapl 138 >> >> Check this commit >> >> >> https://mail.sasken.com/OWA/redir.aspx?C=ded1d3bc21834b138e93aa6e04f85155&URL=http%3a%2f%2fgit.kernel.org%2f%3fp%3dlinux%2fkernel%2fgit%2fkhilman%2flinux-davinci.git%3ba%3dcommitdiff%3bh%3d6c18c91b3a6db6169998b54df12c9d53e74999f3 >> >> This patch adds initial support for the Hawkboard-L138 system >> It is under the machine name "omapl138_hawkboard". >> This system is based on the da850 davinci CPU architecture. >> Information on these system may be found at http://www.hawkboard.org. >> Basic support for the UART console is included in this patch. >> It's tested with latest Angstrom File Systems like ramdisk >> from http://alturl.com/imb45. >> >> >> Some old file systems used to open all the Serial Ports but in OMAP >> l138 the uart 1 is multiplexed and generate the spurious interrupt Try >> with latest Argo File Systems >> >> >> Regards >> >> Victor Rodriguez >> >> >> >> Regards >> >> >> >> Victor Rodriguez >> >> >> >> > Thanks for support. >> >> > Regards, >> >> > Nicolas >> >> > >> >> > >> >> > >> >> > _______________________________________________ >> >> > Davinci-linux-open-source mailing list >> >> > Davinci-linux-open-source at linux.davincidsp.com >> >> > >> >> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source >> >> > >> >> > >> > >> > > > Victor, > Sorry for top post, gmail automaticlly top post. > I tried the file system with my current kernel image and I got the same > error. Then I tried the linux image provided into the tar generated by the > siteweb but I am not able to boot it because I need an other JTAG ID that > the default one because of my silicon revision. > I checked to the patch and I got the same configuration. > Do you have any idea what I should change into my kernel source code to > solve the uart issue? > Thank you > Nicolas > Hi Nicolas I would like to see the log file, another thing witch hardware are you using ? it is important because i know th reason on hawk board but i do not have any other hardware to test it. Actually you are facing a problem that we had some time ago check this thread http://davinci-linux-open-source.1494791.n2.nabble.com/PATCH-v5-davinci-Initial-support-for-Omapl138-Hawkboard-td5508030.html#a5511016 but could be something different please send your log and which hardware are you using Regards Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 14 22:08:17 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:17 -0500 Subject: [PATCH v4 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-2-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..2220105 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,54 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static __init void omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3; + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return; + + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + if (ret) { + pr_warning("%s: " + "cpgmac/mii mux setup failed: %d\n", __func__, ret); + return; + } + + pr_info("EMAC: MII PHY configured\n"); + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: " + "emac registration failed: %d\n", __func__, ret); + return; +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +78,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:18 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:18 -0500 Subject: [PATCH v4 2/9] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-3-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 54 +++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 2220105..5a645ad 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -67,6 +67,55 @@ static __init void omapl138_hawk_config_emac(void) return; } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -80,6 +129,11 @@ static __init void omapl138_hawk_init(void) omapl138_hawk_config_emac(); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("%s: EDMA registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:20 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:20 -0500 Subject: [PATCH v4 4/9] davinci: McASP configuration for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-5-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration for MacASP used on the Hawkboard-L138 system in order to add Audio support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:22 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:22 -0500 Subject: [PATCH v4 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-7-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration to enable MMC/SD and USB-OHCI on the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 4 ++++ arch/arm/mach-davinci/include/mach/mux.h | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..4458bff 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -543,11 +543,15 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false) MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false) /* GPIO function */ + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false) MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false) MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..5d4e0fe 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -908,11 +908,15 @@ enum davinci_da850_index { DA850_NEMA_CS_2, /* GPIO function */ + DA850_GPIO2_4, DA850_GPIO2_6, DA850_GPIO2_8, DA850_GPIO2_15, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:19 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:19 -0500 Subject: [PATCH v4 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-4-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..72c6752 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ + MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:21 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:21 -0500 Subject: [PATCH v4 5/9] davinci: Audio support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-6-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 46 +++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 5a645ad..6f76220 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,38 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci Hawkboard audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -134,6 +167,19 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: EDMA registration failed: %d\n", __func__, ret); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("%s: i2c0 registration failed: %d\n", + __func__, ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:23 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:23 -0500 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-8-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 6f76220..87dea28 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define HAWKBOARD_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -150,6 +152,32 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -180,6 +208,28 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); + + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); + if (ret) + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:24 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:24 -0500 Subject: [PATCH v4 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-9-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 4458bff..2a4730e 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,20 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, + }; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, + }; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +401,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:25 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:25 -0500 Subject: [PATCH v4 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287112105-11968-10-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB pen drive In order to connect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 108 +++++++++++++++++++++++++++ 1 files changed, 108 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 87dea28..4658498 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -178,6 +181,109 @@ static struct davinci_mmc_config da850_mmc_config = { .version = MMC_CTLR_VERSION_2, }; +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + printk(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) { + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + return; + } + + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); + + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); + if (ret) { + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + gpio_direction_input(DA850_USB1_OC_PIN); + + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) { + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); + return; + } +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -230,6 +336,8 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: MMC/SD0 registration failed: %d\n", __func__, ret); + omapl138_hawk_usb_init(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Thu Oct 14 22:08:16 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Thu, 14 Oct 2010 22:08:16 -0500 Subject: [PATCH v4 0/9] Add Omapl138-Hawkboard support Message-ID: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (9): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard davinci: ASoC support for Omapl138-Hawkboard davinci: McASP configuration for Omapl138-Hawkboard davinci: Audio support for Omapl138-Hawkboard davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboar davinci: USB clocks for Omapl138-Hawkboard davinci: USB1.1 support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 308 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 22 ++- arch/arm/mach-davinci/include/mach/mux.h | 4 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 340 insertions(+), 5 deletions(-) From sshtylyov at mvista.com Fri Oct 15 11:14:05 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 15 Oct 2010 20:14:05 +0400 Subject: [PATCH v4 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-2-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-2-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB87DCD.9070107@mvista.com> Hello. On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds EMAC support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 50 +++++++++++++++++++++++++++ > 1 files changed, 50 insertions(+), 0 deletions(-) > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..2220105 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,54 @@ > > #include > #include > +#include > + > +#define HAWKBOARD_PHY_ID "0:07" > + > +static short omapl138_hawk_mii_pins[] __initdata = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 > +}; > + > +static __init void omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfgchip3; > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info =&davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return; > + > + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + > + val = __raw_readl(cfgchip3); > + > + val&= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + if (ret) { > + pr_warning("%s: " > + "cpgmac/mii mux setup failed: %d\n", __func__, ret); > + return; > + } > + > + pr_info("EMAC: MII PHY configured\n"); I said this should *follow* __raw_writel(), not precede it... > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfgchip3); > + > + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; > + > + ret = da8xx_register_emac(); > + if (ret) > + pr_warning("%s: " > + "emac registration failed: %d\n", __func__, ret); > + return; 'return' not needed here. And you've forgotten to enclose it in {} anyway. :-) WBR. Sergei From sshtylyov at mvista.com Fri Oct 15 11:25:28 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 15 Oct 2010 20:25:28 +0400 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <1287112105-11968-8-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-8-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB88078.7050504@mvista.com> Hello. On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds MMC/SD support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 6f76220..87dea28 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -180,6 +208,28 @@ static __init void omapl138_hawk_init(void) > pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); > da8xx_register_mcasp(0,&omapl138_hawk_snd_data); I'd put all the following into a sperate function. > + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); > + if (ret) > + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", > + __func__, ret); > + > + ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); > + if (ret) > + pr_warning("%s: can not open GPIO %d\n", > + __func__, DA850_HAWK_MMCSD_CD_PIN); > + gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); You cannot call that if gpio_request{} failed. > + ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); > + if (ret) > + pr_warning("%s: can not open GPIO %d\n", > + __func__, DA850_HAWK_MMCSD_WP_PIN); > + gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); You cannot call that if gpio_request{} failed. > + ret = da8xx_register_mmcsd0(&da850_mmc_config); > + if (ret) > + pr_warning("%s: MMC/SD0 registration failed: %d\n", > + __func__, ret); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " WBR, Sergei From sshtylyov at mvista.com Fri Oct 15 11:25:38 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 15 Oct 2010 20:25:38 +0400 Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> <4CB73AD5.2060907@mvista.com> Message-ID: <4CB88082.5080901@mvista.com> Hello. On 10/15/10 01:44, Victor Rodriguez wrote: >>> From: Victor Rodriguez >>> This patch adds EMAC support for the Hawkboard-L138 system >>> Signed-off-by: Victor Rodriguez [...] >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index c472dd8..3ae5178 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> @@ -19,6 +19,53 @@ >>> >>> #include >>> #include >>> +#include >>> + >>> +#define HAWKBOARD_PHY_ID "0:07" >>> + >>> +static short omapl138_hawk_mii_pins[] __initdata = { >>> + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >>> + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >>> + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >>> + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >>> + DA850_MDIO_D, >>> + -1 >>> +}; >>> + >>> +static int __init omapl138_hawk_config_emac(void) >>> +{ >>> + void __iomem *cfgchip3; >>> + int ret; >>> + u32 val; >>> + struct davinci_soc_info *soc_info =&davinci_soc_info; >>> + >>> + if (!machine_is_omapl138_hawkboard()) >>> + return 0; >>> + >>> + cfgchip3 = DA8XSYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); >> Could be initializer... > I do not understand this I mean you could assign 'cfgchip3' right when you declare it. >>> + val = __raw_readl(cfgchip3); >>> + >>> + val&= ~BIT(8); >>> + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); >>> + pr_info("EMAC: MII PHY configured\n"); >> I think this pr_info() should follow __raw_writel() call. > Ok >>> + if (ret) >>> + pr_warning("%s: " >>> + "cpgmac/mii mux setup failed: %d\n", __func__, >>> ret); >> You should return here. >>> + >>> + /* configure the CFGCHIP3 register for MII */ >>> + __raw_writel(val, cfgchip3); >>> + >>> + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; >>> + >>> + ret = da8xx_register_emac(); >>> + if (ret) >>> + pr_warning("%s: " >>> + "emac registration failed: %d\n", __func__, ret); >>> + return 0; >> Why this function returns anything at all if it'a always 0, and the result >> is ignored? >>> @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) >>> >>> davinci_serial_init(&omapl138_hawk_uart_config); >>> + ret = omapl138_hawk_config_emac(); >> >> Why assign 'ret', if you're ignoring the result? > Sorry my mistake I forgot to check this, please check the nest patch > maybe it is a better implementation [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..35bcea1 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,53 @@ > > #include > #include > +#include > + > +#define HAWKBOARD_PHY_ID "0:07" > + > +static short omapl138_hawk_mii_pins[] __initdata = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 > +}; > + > +static __init void omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfgchip3; > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info =&davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return; > + > + cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + > + val = __raw_readl(cfgchip3); > + > + val&= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + if (ret) > + pr_warning("%s: " > + "cpgmac/mii mux setup failed: %d\n", __func__, ret); > + return; Should enclose these two statements in {} and fix indentation. > + > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfgchip3); > + pr_info("EMAC: MII PHY configured\n"); > + > + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; > + > + ret = da8xx_register_emac(); > + if (ret) > + pr_warning("%s: " > + "emac registration failed: %d\n", __func__, ret); > + return; 'return' is useless here, and it should've been enclosed into {}... WBR. Sergei From sshtylyov at mvista.com Fri Oct 15 11:27:24 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 15 Oct 2010 20:27:24 +0400 Subject: [PATCH v4 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-9-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-9-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB880EC.3000909@mvista.com> Hello. On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 4458bff..2a4730e 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -345,6 +345,20 @@ static struct clk aemif_clk = { > .flags = ALWAYS_ENABLED, > }; > > +static struct clk usb11_clk = { > + .name = "usb11", > + .parent =&pll0_sysclk4, > + .lpsc = DA8XX_LPSC1_USB11, > + .gpsc = 1, > + }; This } should be at the start of line. > + > +static struct clk usb20_clk = { > + .name = "usb20", > + .parent =&pll0_sysclk2, > + .lpsc = DA8XX_LPSC1_USB20, > + .gpsc = 1, > + }; Same comment. WBR, Sergei From sshtylyov at mvista.com Fri Oct 15 11:32:48 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 15 Oct 2010 20:32:48 +0400 Subject: [PATCH v4 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <1287112105-11968-10-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-10-git-send-email-vm.rod25@gmail.com> Message-ID: <4CB88230.7000501@mvista.com> Hello. On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > This patch adds USB1.1 support for the Hawkboard-L138 system > Signed-off-by: Victor Rodriguez [...] > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 87dea28..4658498 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c [...] > @@ -178,6 +181,109 @@ static struct davinci_mmc_config da850_mmc_config = { > .version = MMC_CTLR_VERSION_2, > }; > > +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); > +static da8xx_ocic_handler_t hawk_usb_ocic_handler; > + > +static const short da850_hawk_usb11_pins[] = { > + DA850_GPIO2_4, DA850_GPIO6_13, > + -1 > +}; An empty wouldn't hurt here. Sorry if I overlooked this before... > +static int hawk_usb_set_power(unsigned port, int on) > +{ > + gpio_set_value(DA850_USB1_VBUS_PIN, on); > + return 0; > +} > + > +static int hawk_usb_get_power(unsigned port) > +{ > + return gpio_get_value(DA850_USB1_VBUS_PIN); > +} > + > +static int hawk_usb_get_oci(unsigned port) > +{ > + return !gpio_get_value(DA850_USB1_OC_PIN); > +} > + > +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) > +{ > + int irq = gpio_to_irq(DA850_USB1_OC_PIN); > + int error = 0; > + > + if (handler != NULL) { > + hawk_usb_ocic_handler = handler; > + > + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, > + IRQF_DISABLED | IRQF_TRIGGER_RISING | > + IRQF_TRIGGER_FALLING, > + "OHCI over-current indicator", NULL); > + if (error) > + printk(KERN_ERR "%s: could not request IRQ to watch " > + "over-current indicator changes\n", __func__); pr_err() please. > + } else > + free_irq(irq, NULL); > + > + return error; > +} > + > +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { > + .set_power = hawk_usb_set_power, > + .get_power = hawk_usb_get_power, > + .get_oci = hawk_usb_get_oci, > + .ocic_notify = hawk_usb_ocic_notify, > + /* TPS2087 switch @ 5V */ > + .potpgt = (3 + 1) / 2, /* 3 ms max */ > +}; > + > +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) > +{ > + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); > + return IRQ_HANDLED; > +} > + > +static __init void omapl138_hawk_usb_init(void) > +{ > + int ret; > + u32 cfgchip2; > + > + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); > + if (ret) { > + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", > + __func__, ret); > + return; > + } > + > + /* > + * Setup the Ref. clock frequency for the HAWK at 24 MHz. > + */ > + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + cfgchip2 &= ~CFGCHIP2_REFFREQ; > + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; > + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + > + ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); > + if (ret) { > + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " > + "power control: %d\n", __func__, ret); pr_err() please. > + return; > + } > + gpio_direction_output(DA850_USB1_VBUS_PIN, 0); > + > + ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); > + if (ret) { > + printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " > + "over-current indicator: %d\n", __func__, ret); pr_err() please. > + return; > + } > + gpio_direction_input(DA850_USB1_OC_PIN); > + > + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); > + if (ret) { > + pr_warning("%s: USB 1.1 registration failed: %d\n", > + __func__, ret); > + return; 'return' is useless here... > + } > +} > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; WBR, Sergei From grant.likely at secretlab.ca Sat Oct 16 00:00:55 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Fri, 15 Oct 2010 23:00:55 -0600 Subject: [PATCH 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287081535-2864-2-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-2-git-send-email-cyril@ti.com> Message-ID: <20101016050055.GH21170@angua.secretlab.ca> On Thu, Oct 14, 2010 at 02:38:44PM -0400, Cyril Chemparathy wrote: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > This patch adds a driver for this controller device. The driver does not > expose a user-land interface. Protocol drivers built on top of this layer are > expected to remain in-kernel. > > Signed-off-by: Cyril Chemparathy Hi Cyril, Overall the driver looks pretty clean, but I have an issue with the usage model (see below). > --- > arch/arm/mach-davinci/include/mach/ti_ssp.h | 92 ++++++ > drivers/misc/Kconfig | 11 + > drivers/misc/Makefile | 1 + > drivers/misc/ti_ssp.c | 443 +++++++++++++++++++++++++++ > 4 files changed, 547 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h > create mode 100644 drivers/misc/ti_ssp.c > > diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h > new file mode 100644 > index 0000000..8365101 > --- /dev/null > +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h > @@ -0,0 +1,92 @@ > +/* > + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#ifndef __TI_SSP_H__ > +#define __TI_SSP_H__ > + > +struct ti_ssp_data { > + unsigned long out_clock; > +}; > + > +struct ti_ssp_port_data { > + const char *ssp_dev_name; > + int port; > + unsigned long iosel; /* see note below */ > + unsigned long config; > +}; > + > +struct ti_ssp_port; > + > +/* > + * Sequencer port IO pin configuration bits. These do not correlate 1-1 with > + * the hardware. The iosel field in the port data combines iosel1 and iosel2, > + * and is therefore not a direct map to register space. It is best to use the > + * macros below to construct iosel values. > + * > + * least significant 16 bits --> iosel1 > + * most significant 16 bits --> iosel2 > + */ > + > +#define SSP_IN 0x0000 > +#define SSP_DATA 0x0001 > +#define SSP_CLOCK 0x0002 > +#define SSP_CHIPSEL 0x0003 > +#define SSP_OUT 0x0004 > +#define SSP_PIN_SEL(pin, v) ((v) << ((pin) * 3)) > +#define SSP_PIN_MASK(pin) SSP_PIN_SEL(pin, 0x7) > +#define SSP_INPUT_SEL(pin) ((pin) << 16) > + > +/* Sequencer port config bits */ > +#define SSP_EARLY_DIN BIT(8) > +#define SSP_DELAY_DOUT BIT(9) > + > +/* Sequence map definitions */ > +#define SSP_CLK_HIGH BIT(0) > +#define SSP_CLK_LOW 0 > +#define SSP_DATA_HIGH BIT(1) > +#define SSP_DATA_LOW 0 > +#define SSP_CS_HIGH BIT(2) > +#define SSP_CS_LOW 0 > +#define SSP_OUT_MODE BIT(3) > +#define SSP_IN_MODE 0 > +#define SSP_DATA_REG BIT(4) > +#define SSP_ADDR_REG 0 > + > +#define SSP_OPCODE_DIRECT ((0x0) << 5) > +#define SSP_OPCODE_TOGGLE ((0x1) << 5) > +#define SSP_OPCODE_SHIFT ((0x2) << 5) > +#define SSP_OPCODE_BRANCH0 ((0x4) << 5) > +#define SSP_OPCODE_BRANCH1 ((0x5) << 5) > +#define SSP_OPCODE_BRANCH ((0x6) << 5) > +#define SSP_OPCODE_STOP ((0x7) << 5) > +#define SSP_BRANCH(addr) ((addr) << 8) > +#define SSP_COUNT(cycles) ((cycles) << 8) > + > +struct ti_ssp_port *ti_ssp_open(const struct ti_ssp_port_data *data); > +int ti_ssp_close(struct ti_ssp_port *dev); > +int ti_ssp_dumpregs(struct ti_ssp_port *dev); > +int ti_ssp_raw_read(struct ti_ssp_port *dev); > +int ti_ssp_raw_write(struct ti_ssp_port *dev, u32 val); > +int ti_ssp_load(struct ti_ssp_port *dev, int offs, u32* prog, int len); > +int ti_ssp_run(struct ti_ssp_port *dev, u32 pc, u32 input, u32 *output); > +int ti_ssp_set_mode(struct ti_ssp_port *dev, int mode); > +int ti_ssp_set_iosel(struct ti_ssp_port *dev, u32 iosel); > + > +#endif /* __TI_SSP_H__ */ > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig > index b743312..9fb8470 100644 > --- a/drivers/misc/Kconfig > +++ b/drivers/misc/Kconfig > @@ -390,6 +390,17 @@ config BMP085 > To compile this driver as a module, choose M here: the > module will be called bmp085. > > +config TI_SSP > + depends on ARCH_DAVINCI_TNETV107X > + tristate "Sequencer Serial Port support" > + default y > + ---help--- > + Say Y here if you want support for the Sequencer Serial Port > + in a Texas Instruments TNETV107X SoC. > + > + To compile this driver as a module, choose M here: the > + module will be called ti_ssp. > + > source "drivers/misc/c2port/Kconfig" > source "drivers/misc/eeprom/Kconfig" > source "drivers/misc/cb710/Kconfig" > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile > index 42eab95..7568100 100644 > --- a/drivers/misc/Makefile > +++ b/drivers/misc/Makefile > @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o > obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o > obj-$(CONFIG_DS1682) += ds1682.o > obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o > +obj-$(CONFIG_TI_SSP) += ti_ssp.o > obj-$(CONFIG_C2PORT) += c2port/ > obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ > obj-$(CONFIG_HMC6352) += hmc6352.o > diff --git a/drivers/misc/ti_ssp.c b/drivers/misc/ti_ssp.c > new file mode 100644 > index 0000000..edbc94d > --- /dev/null > +++ b/drivers/misc/ti_ssp.c > @@ -0,0 +1,443 @@ > +/* > + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +/* Register Offsets */ > +#define SSP_REG_REV 0x00 > +#define SSP_REG_IOSEL_1 0x04 > +#define SSP_REG_IOSEL_2 0x08 > +#define SSP_REG_PREDIV 0x0c > +#define SSP_REG_INTR_STAT 0x10 > +#define SSP_REG_INTR_EN 0x14 > +#define SSP_REG_TEST_CTRL 0x18 > + > +/* Per port registers */ > +#define SSP_PORT_REG_CFG_2 0x00 > +#define SSP_PORT_REG_ADDR 0x04 > +#define SSP_PORT_REG_DATA 0x08 > +#define SSP_PORT_REG_CFG_1 0x0c > +#define SSP_PORT_REG_STATE 0x10 > + > +#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) > +#define SSP_PORT_CLKRATE_MASK 0x0f > + > +#define SSP_SEQRAM_WR_EN BIT(4) > +#define SSP_SEQRAM_RD_EN BIT(5) > +#define SSP_START BIT(15) > +#define SSP_BUSY BIT(10) > +#define SSP_PORT_ASL BIT(7) > +#define SSP_PORT_CFO1 BIT(6) > + > +#define SSP_PORT_SEQRAM_SIZE 32 > + > +static const int ssp_port_base[] = {0x040, 0x080}; > +static const int ssp_port_seqram[] = {0x100, 0x180}; > + > +/* Register Access Macros */ > +#define ssp_read(ssp, reg) __raw_readl((ssp)->regs + SSP_REG_##reg) > +#define ssp_write(ssp, reg, val) __raw_writel(val, (ssp)->regs + SSP_REG_##reg) > + > +#define ssp_rmw(ssp, reg, mask, bits) \ > + ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~(mask)) | (bits)) > + > +#define ssp_port_read(ssp, port, reg) \ > + __raw_readl((ssp)->regs + ssp_port_base[port] + \ > + SSP_PORT_REG_##reg) > + > +#define ssp_port_write(ssp, port, reg, val) \ > + __raw_writel(val, (ssp)->regs + ssp_port_base[port] + \ > + SSP_PORT_REG_##reg) > + > +#define ssp_port_rmw(ssp, port, reg, mask, bits) \ > + ssp_port_write(ssp, port, reg, \ > + (ssp_port_read(ssp, port, reg) & ~(mask)) | (bits)) > + > +#define ssp_port_clr_bits(ssp, port, reg, bits) \ > + ssp_port_rmw(ssp, port, reg, bits, 0) > + > +#define ssp_port_set_bits(ssp, port, reg, bits) \ > + ssp_port_rmw(ssp, port, reg, 0, bits) Consider programming in c rather than preprocessor. You could use static inlines here. > + > +struct ti_ssp { > + struct resource *res; > + void __iomem *regs; > + struct timer_list timer; > + struct ti_ssp_port *ports[2]; > + spinlock_t lock; > + struct clk *clk; > + struct device *dev; > +}; > + > +struct ti_ssp_port { > + int num; > + struct ti_ssp *ssp; > + spinlock_t lock; > +}; > + > +struct ti_ssp_port *ti_ssp_open(const struct ti_ssp_port_data *data) > +{ > + struct ti_ssp *ssp; > + struct ti_ssp_port *port; > + struct device *dev; > + int error = 0; > + > + dev = bus_find_device_by_name(&platform_bus_type, NULL, > + data->ssp_dev_name); > + if (!dev || !dev->driver) > + return ERR_PTR(-ENODEV); > + > + if (!get_device(dev)) > + return ERR_PTR(-ENODEV); > + > + ssp = platform_get_drvdata(to_platform_device(dev)); > + if (!ssp) { > + error = -ENODEV; > + goto error_put; > + } > + > + port = kzalloc(sizeof(*port), GFP_KERNEL); > + if (!port) { > + error = -ENOMEM; > + goto error_put; > + } > + > + port->num = data->port; > + port->ssp = ssp; > + spin_lock_init(&port->lock); > + > + spin_lock(&ssp->lock); > + > + if (ssp->ports[port->num]) { > + error = -EBUSY; > + goto error_unlock; > + } > + > + ssp->ports[port->num] = port; > + > + spin_unlock(&ssp->lock); > + > + ti_ssp_set_iosel(port, data->iosel); > + > + spin_lock(&port->lock); > + ssp_port_rmw(ssp, port->num, CFG_1, SSP_PORT_CONFIG_MASK, > + data->config); > + ssp_port_rmw(ssp, port->num, CFG_2, SSP_PORT_CLKRATE_MASK, 0); > + spin_unlock(&port->lock); > + > + return port; > + > +error_unlock: > + spin_unlock(&ssp->lock); > +error_put: > + put_device(dev); > + return ERR_PTR(error); > +} > +EXPORT_SYMBOL(ti_ssp_open); I'm not thrilled with the ti_ssp_open()/ti_ssp_close() usage model. It appears that the usage model is the board code registers an pile of platform_devices, one for the ssp, and one for each of the behaviours on top of it. Then the various driver instances have to figure out how to find each other and whether or not they are related. Am I correct? Rather than doing an end-run around the Linux driver model, I strongly recommend using the model to solve your problem. Register only the ssp platform_device in the board support code and pass it data about the intended behaviour (via platform data). When it gets probed, it can then register additional platform devices which will get probed by the requested driver. That way the specific ssp device instance data can be passed reliably to the spi/i2c/whatever driver without any ambiguity, without any uncertainty about whether a port is 'busy', and without the need of these open/close routines. (Hint: The trick is to set the platform_device's pdev->dev.parent pointer to make use of the Linux device model's hierarchy). > + > +int ti_ssp_close(struct ti_ssp_port *port) > +{ > + if (!port || !port->ssp) > + return -EINVAL; > + port->ssp->ports[port->num] = NULL; > + put_device(port->ssp->dev); > + kfree(port); > + return 0; > +} > +EXPORT_SYMBOL(ti_ssp_close); > + > +int ti_ssp_set_mode(struct ti_ssp_port *port, int mode) > +{ > + if (!port || !port->ssp) > + return -EINVAL; > + > + spin_lock(&port->lock); > + mode &= SSP_PORT_CONFIG_MASK; > + ssp_port_rmw(port->ssp, port->num, CFG_1, SSP_PORT_CONFIG_MASK, mode); > + spin_unlock(&port->lock); > + > + return 0; > +} > +EXPORT_SYMBOL(ti_ssp_set_mode); > + > +int ti_ssp_set_iosel(struct ti_ssp_port *port, u32 iosel) > +{ > + unsigned int val; > + > + if (!port || !port->ssp) > + return -EINVAL; > + > + spin_lock(&port->lock); > + > + /* IOSEL1 gets the least significant 16 bits */ > + val = ssp_read(port->ssp, IOSEL_1); > + val &= 0xffff << (port->num ? 0 : 16); > + val |= (iosel & 0xffff) << (port->num ? 16 : 0); > + ssp_write(port->ssp, IOSEL_1, val); > + > + /* IOSEL2 gets the most significant 16 bits */ > + val = ssp_read(port->ssp, IOSEL_2); > + val &= 0x0007 << (port->num ? 0 : 16); > + val |= (iosel & 0x00070000) >> (port->num ? 0 : 16); > + ssp_write(port->ssp, IOSEL_2, val); > + > + spin_unlock(&port->lock); > + > + return 0; > +} > +EXPORT_SYMBOL(ti_ssp_set_iosel); > + > +int ti_ssp_load(struct ti_ssp_port *port, int offs, u32* prog, int len) > +{ > + int i; > + > + if (!port || !port->ssp) > + return -EINVAL; > + > + if (len > SSP_PORT_SEQRAM_SIZE) > + return -ENOSPC; > + > + spin_lock(&port->lock); > + > + /* Enable SeqRAM access */ > + ssp_port_set_bits(port->ssp, port->num, CFG_2, SSP_SEQRAM_WR_EN); > + > + /* Copy code */ > + for (i = 0; i < len; i++) { > + __raw_writel(prog[i], port->ssp->regs + offs + 4*i + > + ssp_port_seqram[port->num]); > + } > + > + /* Disable SeqRAM access */ > + ssp_port_clr_bits(port->ssp, port->num, CFG_2, SSP_SEQRAM_WR_EN); > + > + spin_unlock(&port->lock); > + > + return 0; > +} > +EXPORT_SYMBOL(ti_ssp_load); > + > +int ti_ssp_raw_read(struct ti_ssp_port *port) > +{ > + u32 val; > + > + if (!port || !port->ssp) > + return -EINVAL; > + > + val = ssp_read(port->ssp, IOSEL_2); > + val >>= (port->num ? 27 : 11); > + > + return val & 0x0f; > +} > +EXPORT_SYMBOL(ti_ssp_raw_read); > + > +int ti_ssp_raw_write(struct ti_ssp_port *port, u32 val) > +{ > + u32 mask; > + > + if (!port || !port->ssp) > + return -EINVAL; > + > + spin_lock(&port->ssp->lock); > + val &= 0x0f; > + val <<= (port->num ? 22 : 6); > + mask = 0x0f; > + mask <<= (port->num ? 22 : 6); > + ssp_rmw(port->ssp, IOSEL_2, mask, val); > + spin_unlock(&port->ssp->lock); > + > + return 0; > +} > +EXPORT_SYMBOL(ti_ssp_raw_write); > + > +int ti_ssp_run(struct ti_ssp_port *port, u32 pc, u32 input, u32 *output) > +{ > + struct ti_ssp *ssp; > + int count; > + > + if (!port || !port->ssp) > + return -EINVAL; > + ssp = port->ssp; > + > + if (pc & ~(0x3f)) > + return -EINVAL; > + > + ssp_port_write(ssp, port->num, ADDR, input >> 16); > + ssp_port_write(ssp, port->num, DATA, input & 0xffff); > + ssp_port_rmw(ssp, port->num, CFG_1, 0x3f, pc); > + > + ssp_port_set_bits(ssp, port->num, CFG_1, SSP_START); > + > + for (count = 10000; count; count--) { > + if ((ssp_port_read(ssp, port->num, CFG_1) & SSP_BUSY) == 0) > + break; > + udelay(1); > + } > + > + if (output) { > + *(output) = (ssp_port_read(ssp, port->num, ADDR) << 16) | > + (ssp_port_read(ssp, port->num, DATA) & 0xffff); > + } > + > + if (!count) { > + dev_err(ssp->dev, "timed out waiting for SSP operation\n"); > + return -EIO; > + } > + > + /* return stop address */ > + return ssp_port_read(ssp, port->num, STATE) & 0x3f; > +} > +EXPORT_SYMBOL(ti_ssp_run); > + > +static int __devinit ti_ssp_probe(struct platform_device *pdev) > +{ > + static struct ti_ssp *ssp; > + const struct ti_ssp_data *pdata = pdev->dev.platform_data; > + int ret = 0, prediv = 0xff; > + unsigned long sysclk; > + struct device *dev = &pdev->dev; > + > + ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); > + if (!ssp) { > + dev_err(dev, "cannot allocate device info\n"); > + return -ENOMEM; > + } > + > + ssp->dev = dev; > + platform_set_drvdata(pdev, ssp); > + > + ret = -ENODEV; > + ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!ssp->res) { > + dev_err(dev, "cannot determine register area\n"); > + goto error_res; > + } > + > + ret = -EINVAL; > + if (!request_mem_region(ssp->res->start, resource_size(ssp->res), > + pdev->name)) { > + dev_err(dev, "cannot claim register memory\n"); > + goto error_res; > + } > + > + ret = -ENOMEM; > + ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); > + if (!ssp->regs) { > + dev_err(dev, "cannot map register memory\n"); > + goto error_map; > + } > + > + ret = -EINVAL; > + ssp->clk = clk_get(dev, NULL); > + if (IS_ERR(ssp->clk)) { > + dev_err(dev, "cannot claim device clock\n"); > + goto error_clk; > + } > + > + spin_lock_init(&ssp->lock); > + > + platform_set_drvdata(pdev, ssp); > + > + /* Power on and initialize SSP */ > + ret = clk_enable(ssp->clk); > + if (ret) > + goto error_enable; > + > + /* Reset registers to a sensible known state */ > + ssp_write(ssp, IOSEL_1, 0); > + ssp_write(ssp, IOSEL_2, 0); > + ssp_write(ssp, INTR_EN, 0); > + ssp_write(ssp, TEST_CTRL, 0); > + ssp_port_write(ssp, 0, CFG_1, SSP_PORT_ASL); > + ssp_port_write(ssp, 1, CFG_1, SSP_PORT_ASL); > + ssp_port_write(ssp, 0, CFG_2, SSP_PORT_CFO1); > + ssp_port_write(ssp, 1, CFG_2, SSP_PORT_CFO1); > + > + sysclk = clk_get_rate(ssp->clk); > + if (pdata && pdata->out_clock) > + prediv = (sysclk / pdata->out_clock) - 1; > + prediv = clamp(prediv, 0, 0xff); > + ssp_rmw(ssp, PREDIV, 0xff, prediv); > + > + return 0; > + > +error_enable: > + clk_put(ssp->clk); > +error_clk: > + iounmap(ssp->regs); > +error_map: > + release_mem_region(ssp->res->start, resource_size(ssp->res)); > +error_res: > + kfree(ssp); > + return ret; > +} > + > +static int __devexit ti_ssp_remove(struct platform_device *pdev) > +{ > + struct ti_ssp *ssp = platform_get_drvdata(pdev); > + > + clk_disable(ssp->clk); > + clk_put(ssp->clk); > + iounmap(ssp->regs); > + release_mem_region(ssp->res->start, resource_size(ssp->res)); > + kfree(ssp); > + platform_set_drvdata(pdev, NULL); > + return 0; > +} > + > +static struct platform_driver ti_ssp_driver = { > + .probe = ti_ssp_probe, > + .remove = __devexit_p(ti_ssp_remove), > + .driver.name = "ti-ssp", > + .driver.owner = THIS_MODULE, > +}; Personally, I prefer the following form (comment goes for the whole series): static struct platform_driver ti_ssp_driver = { .probe = ti_ssp_probe, .remove = __devexit_p(ti_ssp_remove), .driver = { .name = "ti-ssp", .owner = THIS_MODULE, }, }; > + > +static int __init ti_ssp_init(void) > +{ > + return platform_driver_register(&ti_ssp_driver); > +} > + > +static void __exit ti_ssp_exit(void) > +{ > + platform_driver_unregister(&ti_ssp_driver); > +} > + > +arch_initcall_sync(ti_ssp_init); Keep the initicall line together with the ti_ssp_init definition (goes for the whole series). > +module_exit(ti_ssp_exit); > + > +MODULE_AUTHOR("Cyril Chemparathy"); > +MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); > +MODULE_ALIAS("platform:ti_ssp"); > +MODULE_LICENSE("GPL"); > -- > 1.7.0.4 > > > ------------------------------------------------------------------------------ > Beautiful is writing same markup. Internet Explorer 9 supports > standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3. > Spend less time writing and rewriting code and more time creating great > experiences on the web. Be a part of the beta today. > http://p.sf.net/sfu/beautyoftheweb > _______________________________________________ > spi-devel-general mailing list > spi-devel-general at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/spi-devel-general From grant.likely at secretlab.ca Sat Oct 16 00:05:38 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Fri, 15 Oct 2010 23:05:38 -0600 Subject: [PATCH 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1287081535-2864-5-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-5-git-send-email-cyril@ti.com> Message-ID: <20101016050538.GI21170@angua.secretlab.ca> On Thu, Oct 14, 2010 at 02:38:47PM -0400, Cyril Chemparathy wrote: > This patch adds an SPI master implementation that operates on top of an > underlying TI-SSP port. > > Signed-off-by: Cyril Chemparathy The driver looks good, but as mentioned in my previous comment, I'd like to see the usage model fixed to make proper use of the linux driver model before I ack it. g. > --- > arch/arm/mach-davinci/include/mach/ti_ssp.h | 6 + > drivers/spi/Kconfig | 6 + > drivers/spi/Makefile | 1 + > drivers/spi/spi_ti_ssp.c | 408 +++++++++++++++++++++++++++ > 4 files changed, 421 insertions(+), 0 deletions(-) > create mode 100644 drivers/spi/spi_ti_ssp.c > > diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h > index 8365101..532b0a3 100644 > --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h > +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h > @@ -32,6 +32,12 @@ struct ti_ssp_port_data { > unsigned long config; > }; > > +struct ti_ssp_spi_data { > + struct ti_ssp_port_data port_data; > + int num_cs; > + void (*select)(int cs); > +}; > + > struct ti_ssp_port; > > /* > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig > index 91c2f4f..c1937e4 100644 > --- a/drivers/spi/Kconfig > +++ b/drivers/spi/Kconfig > @@ -298,6 +298,12 @@ config SPI_STMP3XXX > help > SPI driver for Freescale STMP37xx/378x SoC SSP interface > > +config SPI_TI_SSP > + tristate "TI SSP Controller SPI Driver" > + depends on SPI_MASTER && TI_SSP > + help > + SPI master implementation using a TI sequencer serial port. > + > config SPI_TXX9 > tristate "Toshiba TXx9 SPI controller" > depends on GENERIC_GPIO && CPU_TX49XX > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile > index e9cbd18..953aba7 100644 > --- a/drivers/spi/Makefile > +++ b/drivers/spi/Makefile > @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o > obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o > obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o > obj-$(CONFIG_SPI_TXX9) += spi_txx9.o > +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o > obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o > obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o > obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o > diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c > new file mode 100644 > index 0000000..132684c > --- /dev/null > +++ b/drivers/spi/spi_ti_ssp.c > @@ -0,0 +1,408 @@ > +/* > + * Sequencer Serial Port (SSP) based SPI master driver > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) > + > +struct ti_ssp_spi { > + struct spi_master *master; > + const struct ti_ssp_spi_data *pdata; > + struct device *dev; > + spinlock_t lock; > + struct list_head msg_queue; > + struct completion complete; > + int shutdown:1; > + struct workqueue_struct *workqueue; > + struct work_struct work; > + u8 mode, bpw; > + int cs_active; > + struct ti_ssp_port *ssp; > + u32 pc_en, pc_dis, pc_wr, pc_rd; > +}; > + > +static u32 do_read_data(struct ti_ssp_spi *hw) > +{ > + u32 ret; > + > + ti_ssp_run(hw->ssp, hw->pc_rd, 0, &ret); > + return ret; > +} > + > +static void do_write_data(struct ti_ssp_spi *hw, u32 data) > +{ > + ti_ssp_run(hw->ssp, hw->pc_wr, data << (32 - hw->bpw), NULL); > +} > + > +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, > + struct spi_transfer *t) > +{ > + int count; > + > + if (hw->bpw <= 8) { > + u8 *rx = t->rx_buf; > + const u8 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 1) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } else if (hw->bpw <= 16) { > + u16 *rx = t->rx_buf; > + const u16 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 2) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } else { > + u32 *rx = t->rx_buf; > + const u32 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 4) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } > + > + msg->actual_length += count; /* bytes transferred */ > + > + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", > + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, > + hw->bpw, count, (count < t->len) ? " (under)": ""); > + > + return (count < t->len) ? -EIO : 0; /* left over data */ > +} > + > +static void chip_select(struct ti_ssp_spi *hw, int cs_active) > +{ > + cs_active = !!cs_active; > + if (cs_active == hw->cs_active) > + return; > + ti_ssp_run(hw->ssp, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); > + hw->cs_active = cs_active; > +} > + > +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ > + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) > +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ > + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) > + > +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) > +{ > + int error, idx = 0; > + u32 seqram[16]; > + u32 cs_en, cs_dis, clk; > + u32 topbits, botbits; > + > + mode &= MODE_BITS; > + if (mode == hw->mode && bpw == hw->bpw) > + return 0; > + > + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; > + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; > + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; > + > + /* Construct instructions */ > + > + /* Disable Chip Select */ > + hw->pc_dis = idx; > + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; > + > + /* Enable Chip Select */ > + hw->pc_en = idx; > + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + /* Reads and writes need to be split for bpw > 16 */ > + topbits = (bpw > 16) ? 16 : bpw; > + botbits = bpw - topbits; > + > + /* Write */ > + hw->pc_wr = idx; > + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; > + if (botbits) > + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + /* Read */ > + hw->pc_rd = idx; > + if (botbits) > + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; > + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + error = ti_ssp_load(hw->ssp, 0, seqram, idx); > + if (error < 0) > + return error; > + > + error = ti_ssp_set_mode(hw->ssp, ((mode & SPI_CPHA) ? > + 0 : SSP_EARLY_DIN)); > + if (error < 0) > + return error; > + > + hw->bpw = bpw; > + hw->mode = mode; > + > + return error; > +} > + > +static void ti_ssp_spi_work(struct work_struct *work) > +{ > + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); > + > + spin_lock_irq(&hw->lock); > + > + while (!list_empty(&hw->msg_queue)) { Errant space ' ' before while statement. > + struct spi_message *m; > + struct spi_device *spi; > + struct spi_transfer *t = NULL; > + int status = 0; > + > + m = container_of(hw->msg_queue.next, struct spi_message, > + queue); > + > + list_del_init(&m->queue); > + > + spi = m->spi; > + > + if (hw->pdata->select) > + hw->pdata->select(spi->chip_select); > + > + list_for_each_entry(t, &m->transfers, transfer_list) { > + int bpw = spi->bits_per_word; > + int xfer_status; > + > + if (t->bits_per_word) > + bpw = t->bits_per_word; > + > + if (setup_xfer(hw, bpw, spi->mode) < 0) > + break; > + > + chip_select(hw, 1); > + > + spin_unlock_irq(&hw->lock); > + > + xfer_status = do_transfer(hw, m, t); > + if (xfer_status < 0) > + status = xfer_status; > + > + if (t->delay_usecs) > + udelay(t->delay_usecs); > + > + spin_lock_irq(&hw->lock); > + > + if (t->cs_change) > + chip_select(hw, 0); > + } > + > + chip_select(hw, 0); > + m->status = status; > + m->complete(m->context); > + } > + > + if (hw->shutdown) > + complete(&hw->complete); > + > + spin_unlock_irq(&hw->lock); > +} > + > +static int ti_ssp_spi_setup(struct spi_device *spi) > +{ > + if (spi->bits_per_word > 32) > + return -EINVAL; > + > + return 0; > +} > + > +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) > +{ > + struct ti_ssp_spi *hw; > + struct spi_transfer *t; > + unsigned long flags; > + int error = 0; > + > + m->actual_length = 0; > + m->status = -EINPROGRESS; > + > + hw = spi_master_get_devdata(spi->master); > + > + if (list_empty(&m->transfers) || !m->complete) > + return -EINVAL; > + > + list_for_each_entry(t, &m->transfers, transfer_list) { > + if (t->len && !(t->rx_buf || t->tx_buf)) { > + dev_err(&spi->dev, "invalid xfer, no buffer\n"); > + return -EINVAL; > + } > + > + if (t->len && t->rx_buf && t->tx_buf) { > + dev_err(&spi->dev, "invalid xfer, full duplex\n"); > + return -EINVAL; > + } > + > + if (t->bits_per_word > 32) { > + dev_err(&spi->dev, "invalid xfer width %d\n", > + t->bits_per_word); > + return -EINVAL; > + } > + } > + > + spin_lock_irqsave(&hw->lock, flags); > + if (hw->shutdown) { > + error = -ESHUTDOWN; > + goto error_unlock; > + } > + list_add_tail(&m->queue, &hw->msg_queue); > + queue_work(hw->workqueue, &hw->work); > +error_unlock: > + spin_unlock_irqrestore(&hw->lock, flags); > + return error; > +} > + > +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) > +{ > + const struct ti_ssp_spi_data *pdata; > + struct ti_ssp_spi *hw; > + struct spi_master *master; > + struct device *dev = &pdev->dev; > + int error = 0; > + > + pdata = dev->platform_data; > + if (!pdata) { > + dev_err(dev, "platform data not found\n"); > + return -EINVAL; > + } > + > + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); > + if (!master) { > + dev_err(dev, "cannot allocate SPI master\n"); > + return -ENOMEM; > + } > + > + hw = spi_master_get_devdata(master); > + platform_set_drvdata(pdev, hw); > + > + hw->master = master; > + hw->dev = dev; > + hw->pdata = pdata; > + > + spin_lock_init(&hw->lock); > + init_completion(&hw->complete); > + INIT_LIST_HEAD(&hw->msg_queue); > + INIT_WORK(&hw->work, ti_ssp_spi_work); > + > + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); > + if (!hw->workqueue) { > + error = -ENOMEM; > + dev_err(dev, "work queue creation failed\n"); > + goto error_wq; > + } > + > + hw->ssp = ti_ssp_open(&hw->pdata->port_data); > + if (IS_ERR(hw->ssp)) { > + error = PTR_ERR(hw->ssp); > + dev_err(dev, "ssp open failed (%d)\n", error); > + goto error_open; > + } > + > + master->bus_num = pdev->id; > + master->num_chipselect = hw->pdata->num_cs; > + master->mode_bits = MODE_BITS; > + master->flags = SPI_MASTER_HALF_DUPLEX; > + master->setup = ti_ssp_spi_setup; > + master->transfer = ti_ssp_spi_transfer; > + > + error = spi_register_master(master); > + if (error) { > + dev_err(dev, "master registration failed\n"); > + goto error_reg; > + } > + > + return 0; > + > +error_reg: > + ti_ssp_close(hw->ssp); > +error_open: > + destroy_workqueue(hw->workqueue); > +error_wq: > + spi_master_put(master); > + return error; > +} > + > +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) > +{ > + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); > + int error; > + > + hw->shutdown = 1; > + while (!list_empty(&hw->msg_queue)) { > + error = wait_for_completion_interruptible(&hw->complete); > + if (error < 0) { > + hw->shutdown = 0; > + return error; > + } > + } > + > + ti_ssp_close(hw->ssp); > + destroy_workqueue(hw->workqueue); > + spi_unregister_master(hw->master); > + > + return 0; > +} > + > +static struct platform_driver ti_ssp_spi_driver = { > + .probe = ti_ssp_spi_probe, > + .remove = __devexit_p(ti_ssp_spi_remove), > + .driver.name = "ti-ssp-spi", > + .driver.owner = THIS_MODULE, > +}; > + > +static int __init ti_ssp_spi_init(void) > +{ > + return platform_driver_register(&ti_ssp_spi_driver); > +} > + > +static void __exit ti_ssp_spi_exit(void) > +{ > + platform_driver_unregister(&ti_ssp_spi_driver); > +} > + > +subsys_initcall(ti_ssp_spi_init); > +module_exit(ti_ssp_spi_exit); > + > +MODULE_DESCRIPTION("SSP SPI Master"); > +MODULE_AUTHOR("Cyril Chemparathy"); > +MODULE_ALIAS("platform:spi_ti_ssp"); > +MODULE_LICENSE("GPL"); > -- > 1.7.0.4 > > > ------------------------------------------------------------------------------ > Beautiful is writing same markup. Internet Explorer 9 supports > standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3. > Spend less time writing and rewriting code and more time creating great > experiences on the web. Be a part of the beta today. > http://p.sf.net/sfu/beautyoftheweb > _______________________________________________ > spi-devel-general mailing list > spi-devel-general at lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/spi-devel-general From broonie at opensource.wolfsonmicro.com Sat Oct 16 05:00:39 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Sat, 16 Oct 2010 11:00:39 +0100 Subject: [PATCH 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287081535-2864-7-git-send-email-cyril@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-7-git-send-email-cyril@ti.com> Message-ID: <20101016100039.GA6311@opensource.wolfsonmicro.com> On Thu, Oct 14, 2010 at 02:38:49PM -0400, Cyril Chemparathy wrote: > TPS6524X provides three step-down converters and two general-purpose LDO > voltage regulators. This device is interfaced using SPI. > > Signed-off-by: Cyril Chemparathy My review comments from the previous posting do not appear to have been addressed or responded to? From zlx1318 at 163.com Sat Oct 16 22:46:34 2010 From: zlx1318 at 163.com (=?gbk?B?1cU=?=) Date: Sun, 17 Oct 2010 11:46:34 +0800 (CST) Subject: Davinci-linux-open-source Digest, Vol 58, Issue 52 In-Reply-To: References: Message-ID: Can you give me some mail about DM6467 not omapl138? At 2010-10-17 01:00:00?davinci-linux-open-source-request at linux.davincidsp.com wrote: >Send Davinci-linux-open-source mailing list submissions to > davinci-linux-open-source at linux.davincidsp.com > >To subscribe or unsubscribe via the World Wide Web, visit > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > >or, via email, send a message with subject or body 'help' to > davinci-linux-open-source-request at linux.davincidsp.com > >You can reach the person managing the list at > davinci-linux-open-source-owner at linux.davincidsp.com > >When replying, please edit your Subject line so it is more specific >than "Re: Contents of Davinci-linux-open-source digest..." > > >Today's Topics: > > 1. Re: [PATCH 04/12] spi: add ti-ssp spi master driver (Grant Likely) > 2. Re: [PATCH 06/12] regulator: add driver for tps6524x > regulator (Mark Brown) > > >---------------------------------------------------------------------- > >Message: 1 >Date: Fri, 15 Oct 2010 23:05:38 -0600 >From: Grant Likely >To: Cyril Chemparathy >Cc: spi-devel-general at lists.sourceforge.net, > davinci-linux-open-source at linux.davincidsp.com, > broonie at opensource.wolfsonmicro.com, dbrownell at users.sourceforge.net, > lrg at slimlogic.co.uk >Subject: Re: [PATCH 04/12] spi: add ti-ssp spi master driver >Message-ID: <20101016050538.GI21170 at angua.secretlab.ca> >Content-Type: text/plain; charset=us-ascii > >On Thu, Oct 14, 2010 at 02:38:47PM -0400, Cyril Chemparathy wrote: >> This patch adds an SPI master implementation that operates on top of an >> underlying TI-SSP port. >> >> Signed-off-by: Cyril Chemparathy > >The driver looks good, but as mentioned in my previous comment, I'd >like to see the usage model fixed to make proper use of the linux >driver model before I ack it. > >g. > >> --- >> arch/arm/mach-davinci/include/mach/ti_ssp.h | 6 + >> drivers/spi/Kconfig | 6 + >> drivers/spi/Makefile | 1 + >> drivers/spi/spi_ti_ssp.c | 408 +++++++++++++++++++++++++++ >> 4 files changed, 421 insertions(+), 0 deletions(-) >> create mode 100644 drivers/spi/spi_ti_ssp.c >> >> diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h >> index 8365101..532b0a3 100644 >> --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h >> +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h >> @@ -32,6 +32,12 @@ struct ti_ssp_port_data { >> unsigned long config; >> }; >> >> +struct ti_ssp_spi_data { >> + struct ti_ssp_port_data port_data; >> + int num_cs; >> + void (*select)(int cs); >> +}; >> + >> struct ti_ssp_port; >> >> /* >> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig >> index 91c2f4f..c1937e4 100644 >> --- a/drivers/spi/Kconfig >> +++ b/drivers/spi/Kconfig >> @@ -298,6 +298,12 @@ config SPI_STMP3XXX >> help >> SPI driver for Freescale STMP37xx/378x SoC SSP interface >> >> +config SPI_TI_SSP >> + tristate "TI SSP Controller SPI Driver" >> + depends on SPI_MASTER && TI_SSP >> + help >> + SPI master implementation using a TI sequencer serial port. >> + >> config SPI_TXX9 >> tristate "Toshiba TXx9 SPI controller" >> depends on GENERIC_GPIO && CPU_TX49XX >> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile >> index e9cbd18..953aba7 100644 >> --- a/drivers/spi/Makefile >> +++ b/drivers/spi/Makefile >> @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o >> obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o >> obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o >> obj-$(CONFIG_SPI_TXX9) += spi_txx9.o >> +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o >> obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o >> obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o >> obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o >> diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c >> new file mode 100644 >> index 0000000..132684c >> --- /dev/null >> +++ b/drivers/spi/spi_ti_ssp.c >> @@ -0,0 +1,408 @@ >> +/* >> + * Sequencer Serial Port (SSP) based SPI master driver >> + * >> + * Copyright (C) 2010 Texas Instruments Inc >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + * >> + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include >> + >> +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) >> + >> +struct ti_ssp_spi { >> + struct spi_master *master; >> + const struct ti_ssp_spi_data *pdata; >> + struct device *dev; >> + spinlock_t lock; >> + struct list_head msg_queue; >> + struct completion complete; >> + int shutdown:1; >> + struct workqueue_struct *workqueue; >> + struct work_struct work; >> + u8 mode, bpw; >> + int cs_active; >> + struct ti_ssp_port *ssp; >> + u32 pc_en, pc_dis, pc_wr, pc_rd; >> +}; >> + >> +static u32 do_read_data(struct ti_ssp_spi *hw) >> +{ >> + u32 ret; >> + >> + ti_ssp_run(hw->ssp, hw->pc_rd, 0, &ret); >> + return ret; >> +} >> + >> +static void do_write_data(struct ti_ssp_spi *hw, u32 data) >> +{ >> + ti_ssp_run(hw->ssp, hw->pc_wr, data << (32 - hw->bpw), NULL); >> +} >> + >> +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, >> + struct spi_transfer *t) >> +{ >> + int count; >> + >> + if (hw->bpw <= 8) { >> + u8 *rx = t->rx_buf; >> + const u8 *tx = t->tx_buf; >> + >> + for (count = 0; count < t->len; count += 1) { >> + if (t->tx_buf) >> + do_write_data(hw, *tx++); >> + if (t->rx_buf) >> + *rx++ = do_read_data(hw); >> + } >> + } else if (hw->bpw <= 16) { >> + u16 *rx = t->rx_buf; >> + const u16 *tx = t->tx_buf; >> + >> + for (count = 0; count < t->len; count += 2) { >> + if (t->tx_buf) >> + do_write_data(hw, *tx++); >> + if (t->rx_buf) >> + *rx++ = do_read_data(hw); >> + } >> + } else { >> + u32 *rx = t->rx_buf; >> + const u32 *tx = t->tx_buf; >> + >> + for (count = 0; count < t->len; count += 4) { >> + if (t->tx_buf) >> + do_write_data(hw, *tx++); >> + if (t->rx_buf) >> + *rx++ = do_read_data(hw); >> + } >> + } >> + >> + msg->actual_length += count; /* bytes transferred */ >> + >> + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", >> + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, >> + hw->bpw, count, (count < t->len) ? " (under)": ""); >> + >> + return (count < t->len) ? -EIO : 0; /* left over data */ >> +} >> + >> +static void chip_select(struct ti_ssp_spi *hw, int cs_active) >> +{ >> + cs_active = !!cs_active; >> + if (cs_active == hw->cs_active) >> + return; >> + ti_ssp_run(hw->ssp, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); >> + hw->cs_active = cs_active; >> +} >> + >> +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ >> + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) >> +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ >> + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) >> + >> +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) >> +{ >> + int error, idx = 0; >> + u32 seqram[16]; >> + u32 cs_en, cs_dis, clk; >> + u32 topbits, botbits; >> + >> + mode &= MODE_BITS; >> + if (mode == hw->mode && bpw == hw->bpw) >> + return 0; >> + >> + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; >> + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; >> + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; >> + >> + /* Construct instructions */ >> + >> + /* Disable Chip Select */ >> + hw->pc_dis = idx; >> + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; >> + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; >> + >> + /* Enable Chip Select */ >> + hw->pc_en = idx; >> + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; >> + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; >> + >> + /* Reads and writes need to be split for bpw > 16 */ >> + topbits = (bpw > 16) ? 16 : bpw; >> + botbits = bpw - topbits; >> + >> + /* Write */ >> + hw->pc_wr = idx; >> + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; >> + if (botbits) >> + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; >> + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; >> + >> + /* Read */ >> + hw->pc_rd = idx; >> + if (botbits) >> + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; >> + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; >> + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; >> + >> + error = ti_ssp_load(hw->ssp, 0, seqram, idx); >> + if (error < 0) >> + return error; >> + >> + error = ti_ssp_set_mode(hw->ssp, ((mode & SPI_CPHA) ? >> + 0 : SSP_EARLY_DIN)); >> + if (error < 0) >> + return error; >> + >> + hw->bpw = bpw; >> + hw->mode = mode; >> + >> + return error; >> +} >> + >> +static void ti_ssp_spi_work(struct work_struct *work) >> +{ >> + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); >> + >> + spin_lock_irq(&hw->lock); >> + >> + while (!list_empty(&hw->msg_queue)) { > >Errant space ' ' before while statement. > >> + struct spi_message *m; >> + struct spi_device *spi; >> + struct spi_transfer *t = NULL; >> + int status = 0; >> + >> + m = container_of(hw->msg_queue.next, struct spi_message, >> + queue); >> + >> + list_del_init(&m->queue); >> + >> + spi = m->spi; >> + >> + if (hw->pdata->select) >> + hw->pdata->select(spi->chip_select); >> + >> + list_for_each_entry(t, &m->transfers, transfer_list) { >> + int bpw = spi->bits_per_word; >> + int xfer_status; >> + >> + if (t->bits_per_word) >> + bpw = t->bits_per_word; >> + >> + if (setup_xfer(hw, bpw, spi->mode) < 0) >> + break; >> + >> + chip_select(hw, 1); >> + >> + spin_unlock_irq(&hw->lock); >> + >> + xfer_status = do_transfer(hw, m, t); >> + if (xfer_status < 0) >> + status = xfer_status; >> + >> + if (t->delay_usecs) >> + udelay(t->delay_usecs); >> + >> + spin_lock_irq(&hw->lock); >> + >> + if (t->cs_change) >> + chip_select(hw, 0); >> + } >> + >> + chip_select(hw, 0); >> + m->status = status; >> + m->complete(m->context); >> + } >> + >> + if (hw->shutdown) >> + complete(&hw->complete); >> + >> + spin_unlock_irq(&hw->lock); >> +} >> + >> +static int ti_ssp_spi_setup(struct spi_device *spi) >> +{ >> + if (spi->bits_per_word > 32) >> + return -EINVAL; >> + >> + return 0; >> +} >> + >> +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) >> +{ >> + struct ti_ssp_spi *hw; >> + struct spi_transfer *t; >> + unsigned long flags; >> + int error = 0; >> + >> + m->actual_length = 0; >> + m->status = -EINPROGRESS; >> + >> + hw = spi_master_get_devdata(spi->master); >> + >> + if (list_empty(&m->transfers) || !m->complete) >> + return -EINVAL; >> + >> + list_for_each_entry(t, &m->transfers, transfer_list) { >> + if (t->len && !(t->rx_buf || t->tx_buf)) { >> + dev_err(&spi->dev, "invalid xfer, no buffer\n"); >> + return -EINVAL; >> + } >> + >> + if (t->len && t->rx_buf && t->tx_buf) { >> + dev_err(&spi->dev, "invalid xfer, full duplex\n"); >> + return -EINVAL; >> + } >> + >> + if (t->bits_per_word > 32) { >> + dev_err(&spi->dev, "invalid xfer width %d\n", >> + t->bits_per_word); >> + return -EINVAL; >> + } >> + } >> + >> + spin_lock_irqsave(&hw->lock, flags); >> + if (hw->shutdown) { >> + error = -ESHUTDOWN; >> + goto error_unlock; >> + } >> + list_add_tail(&m->queue, &hw->msg_queue); >> + queue_work(hw->workqueue, &hw->work); >> +error_unlock: >> + spin_unlock_irqrestore(&hw->lock, flags); >> + return error; >> +} >> + >> +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) >> +{ >> + const struct ti_ssp_spi_data *pdata; >> + struct ti_ssp_spi *hw; >> + struct spi_master *master; >> + struct device *dev = &pdev->dev; >> + int error = 0; >> + >> + pdata = dev->platform_data; >> + if (!pdata) { >> + dev_err(dev, "platform data not found\n"); >> + return -EINVAL; >> + } >> + >> + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); >> + if (!master) { >> + dev_err(dev, "cannot allocate SPI master\n"); >> + return -ENOMEM; >> + } >> + >> + hw = spi_master_get_devdata(master); >> + platform_set_drvdata(pdev, hw); >> + >> + hw->master = master; >> + hw->dev = dev; >> + hw->pdata = pdata; >> + >> + spin_lock_init(&hw->lock); >> + init_completion(&hw->complete); >> + INIT_LIST_HEAD(&hw->msg_queue); >> + INIT_WORK(&hw->work, ti_ssp_spi_work); >> + >> + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); >> + if (!hw->workqueue) { >> + error = -ENOMEM; >> + dev_err(dev, "work queue creation failed\n"); >> + goto error_wq; >> + } >> + >> + hw->ssp = ti_ssp_open(&hw->pdata->port_data); >> + if (IS_ERR(hw->ssp)) { >> + error = PTR_ERR(hw->ssp); >> + dev_err(dev, "ssp open failed (%d)\n", error); >> + goto error_open; >> + } >> + >> + master->bus_num = pdev->id; >> + master->num_chipselect = hw->pdata->num_cs; >> + master->mode_bits = MODE_BITS; >> + master->flags = SPI_MASTER_HALF_DUPLEX; >> + master->setup = ti_ssp_spi_setup; >> + master->transfer = ti_ssp_spi_transfer; >> + >> + error = spi_register_master(master); >> + if (error) { >> + dev_err(dev, "master registration failed\n"); >> + goto error_reg; >> + } >> + >> + return 0; >> + >> +error_reg: >> + ti_ssp_close(hw->ssp); >> +error_open: >> + destroy_workqueue(hw->workqueue); >> +error_wq: >> + spi_master_put(master); >> + return error; >> +} >> + >> +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) >> +{ >> + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); >> + int error; >> + >> + hw->shutdown = 1; >> + while (!list_empty(&hw->msg_queue)) { >> + error = wait_for_completion_interruptible(&hw->complete); >> + if (error < 0) { >> + hw->shutdown = 0; >> + return error; >> + } >> + } >> + >> + ti_ssp_close(hw->ssp); >> + destroy_workqueue(hw->workqueue); >> + spi_unregister_master(hw->master); >> + >> + return 0; >> +} >> + >> +static struct platform_driver ti_ssp_spi_driver = { >> + .probe = ti_ssp_spi_probe, >> + .remove = __devexit_p(ti_ssp_spi_remove), >> + .driver.name = "ti-ssp-spi", >> + .driver.owner = THIS_MODULE, >> +}; >> + >> +static int __init ti_ssp_spi_init(void) >> +{ >> + return platform_driver_register(&ti_ssp_spi_driver); >> +} >> + >> +static void __exit ti_ssp_spi_exit(void) >> +{ >> + platform_driver_unregister(&ti_ssp_spi_driver); >> +} >> + >> +subsys_initcall(ti_ssp_spi_init); >> +module_exit(ti_ssp_spi_exit); >> + >> +MODULE_DESCRIPTION("SSP SPI Master"); >> +MODULE_AUTHOR("Cyril Chemparathy"); >> +MODULE_ALIAS("platform:spi_ti_ssp"); >> +MODULE_LICENSE("GPL"); >> -- >> 1.7.0.4 >> >> >> ------------------------------------------------------------------------------ >> Beautiful is writing same markup. Internet Explorer 9 supports >> standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3. >> Spend less time writing and rewriting code and more time creating great >> experiences on the web. Be a part of the beta today. >> http://p.sf.net/sfu/beautyoftheweb >> _______________________________________________ >> spi-devel-general mailing list >> spi-devel-general at lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/spi-devel-general > > >------------------------------ > >Message: 2 >Date: Sat, 16 Oct 2010 11:00:39 +0100 >From: Mark Brown >To: Cyril Chemparathy >Cc: spi-devel-general at lists.sourceforge.net, > davinci-linux-open-source at linux.davincidsp.com, > dbrownell at users.sourceforge.net, lrg at slimlogic.co.uk >Subject: Re: [PATCH 06/12] regulator: add driver for tps6524x > regulator >Message-ID: <20101016100039.GA6311 at opensource.wolfsonmicro.com> >Content-Type: text/plain; charset=us-ascii > >On Thu, Oct 14, 2010 at 02:38:49PM -0400, Cyril Chemparathy wrote: >> TPS6524X provides three step-down converters and two general-purpose LDO >> voltage regulators. This device is interfaced using SPI. >> >> Signed-off-by: Cyril Chemparathy > >My review comments from the previous posting do not appear to have been >addressed or responded to? > > >------------------------------ > >_______________________________________________ >Davinci-linux-open-source mailing list >Davinci-linux-open-source at linux.davincidsp.com >http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > >End of Davinci-linux-open-source Digest, Vol 58, Issue 52 >********************************************************* -------------- next part -------------- An HTML attachment was scrubbed... URL: From krunal.patil at einfochips.com Mon Oct 18 01:13:28 2010 From: krunal.patil at einfochips.com (Krunal Patil) Date: Mon, 18 Oct 2010 11:43:28 +0530 Subject: DM365 OV5642 interface: No video data. Message-ID: <4CBBE588.1060105@einfochips.com> An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: CCDC_registerdump.txt URL: From cyril at ti.com Mon Oct 18 07:50:55 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 08:50:55 -0400 Subject: [PATCH 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <20101014210323.GB14479@opensource.wolfsonmicro.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-7-git-send-email-cyril@ti.com> <20101014210323.GB14479@opensource.wolfsonmicro.com> Message-ID: <4CBC42AF.5000803@ti.com> Hi Mark, Thanks for the feedback. I agree with your comments, and I will make the necessary changes before posting a v2. The one exception being... [...] >> +static const int dcdc1_voltages[] = { >> + 800000, 825000, 850000, 875000, >> + 900000, 925000, 950000, 975000, >> + 1000000, 1025000, 1050000, 1075000, >> + 1100000, 1125000, 1150000, 1175000, >> + 1200000, 1225000, 1250000, 1275000, >> + 1300000, 1325000, 1350000, 1375000, >> + 1400000, 1425000, 1450000, 1475000, >> + 1500000, 1525000, 1550000, 1575000, > > Looks like you could just do the maths for most of these tables, might > be a bit clearer/simpler? Not a major issue either way, though. ... not all of the supplies are linear (e.g. ldo2). Rather than have to deal with both cases (linear and non-linear), enumerating the list of voltages appeared to be simpler. [...] Regards Cyril. From cyril at ti.com Mon Oct 18 08:56:27 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 09:56:27 -0400 Subject: [PATCH 01/12] misc: add driver for sequencer serial port In-Reply-To: <20101016050055.GH21170@angua.secretlab.ca> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-2-git-send-email-cyril@ti.com> <20101016050055.GH21170@angua.secretlab.ca> Message-ID: <4CBC520B.9070502@ti.com> Hi Grant, Thanks for the feedback, I will send out an updated v2 with the proposed changes. [...] >> +EXPORT_SYMBOL(ti_ssp_open); > > I'm not thrilled with the ti_ssp_open()/ti_ssp_close() usage model. > It appears that the usage model is the board code registers an pile > of platform_devices, one for the ssp, and one for each of the > behaviours on top of it. Then the various driver instances have to > figure out how to find each other and whether or not they are related. > Am I correct? > > Rather than doing an end-run around the Linux driver model, I strongly > recommend using the model to solve your problem. Register only the > ssp platform_device in the board support code and pass it data about > the intended behaviour (via platform data). When it gets probed, it > can then register additional platform devices which will get probed by > the requested driver. That way the specific ssp device instance data > can be passed reliably to the spi/i2c/whatever driver without any > ambiguity, without any uncertainty about whether a port is 'busy', and > without the need of these open/close routines. > > (Hint: The trick is to set the platform_device's pdev->dev.parent > pointer to make use of the Linux device model's hierarchy). I am not very thrilled with this approach either :-) I had looked at a few other instances where something similar was being done (spi, i2c, mdio, etc.), but felt that defining a new bus type would be an overkill for this. For reference, could you please point me to some other place where something similar is being done? Regards Cyril. From vm.rod25 at gmail.com Mon Oct 18 09:59:26 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 18 Oct 2010 09:59:26 -0500 Subject: [PATCH v4 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <4CB88230.7000501@mvista.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-10-git-send-email-vm.rod25@gmail.com> <4CB88230.7000501@mvista.com> Message-ID: On Fri, Oct 15, 2010 at 11:32 AM, Sergei Shtylyov wrote: > Hello. > > On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds USB1.1 support for the Hawkboard-L138 system > >> Signed-off-by: Victor Rodriguez > > [...] > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index 87dea28..4658498 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > [...] >> >> @@ -178,6 +181,109 @@ static struct davinci_mmc_config da850_mmc_config = >> { >> ? ? ? ?.version ? ? ? ?= MMC_CTLR_VERSION_2, >> ?}; >> >> +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); >> +static da8xx_ocic_handler_t hawk_usb_ocic_handler; >> + >> +static const short da850_hawk_usb11_pins[] = { >> + ? ? ? DA850_GPIO2_4, DA850_GPIO6_13, >> + ? ? ? -1 >> +}; > > ? An empty wouldn't hurt here. Sorry if I overlooked this before... > >> +static int hawk_usb_set_power(unsigned port, int on) >> +{ >> + ? ? ? gpio_set_value(DA850_USB1_VBUS_PIN, on); >> + ? ? ? return 0; >> +} >> + >> +static int hawk_usb_get_power(unsigned port) >> +{ >> + ? ? ? return gpio_get_value(DA850_USB1_VBUS_PIN); >> +} >> + >> +static int hawk_usb_get_oci(unsigned port) >> +{ >> + ? ? ? return !gpio_get_value(DA850_USB1_OC_PIN); >> +} >> + >> +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) >> +{ >> + ? ? ? int irq ? ? ? ? = gpio_to_irq(DA850_USB1_OC_PIN); >> + ? ? ? int error ? ? ? = 0; >> + >> + ? ? ? if (handler != NULL) { >> + ? ? ? ? ? ? ? hawk_usb_ocic_handler = handler; >> + >> + ? ? ? ? ? ? ? error = request_irq(irq, omapl138_hawk_usb_ocic_irq, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_DISABLED | >> IRQF_TRIGGER_RISING | >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQF_TRIGGER_FALLING, >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "OHCI over-current indicator", >> NULL); >> + ? ? ? ? ? ? ? if (error) >> + ? ? ? ? ? ? ? ? ? ? ? printk(KERN_ERR "%s: could not request IRQ to >> watch " >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "over-current indicator changes\n", >> __func__); > > ? pr_err() please. > >> + ? ? ? } else >> + ? ? ? ? ? ? ? free_irq(irq, NULL); >> + >> + ? ? ? return error; >> +} >> + >> +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { >> + ? ? ? .set_power ? ? ?= hawk_usb_set_power, >> + ? ? ? .get_power ? ? ?= hawk_usb_get_power, >> + ? ? ? .get_oci ? ? ? ?= hawk_usb_get_oci, >> + ? ? ? .ocic_notify ? ?= hawk_usb_ocic_notify, >> + ? ? ? /* TPS2087 switch @ 5V */ >> + ? ? ? .potpgt ? ? ? ? = (3 + 1) / 2, ?/* 3 ms max */ >> +}; >> + >> +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) >> +{ >> + ? ? ? hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); >> + ? ? ? return IRQ_HANDLED; >> +} >> + >> +static __init void omapl138_hawk_usb_init(void) >> +{ >> + ? ? ? int ret; >> + ? ? ? u32 cfgchip2; >> + >> + ? ? ? ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); >> + ? ? ? if (ret) { >> + ? ? ? ? ? ? ? pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> + ? ? ? ? ? ? ? return; >> + ? ? ? } >> + >> + ? ? ? /* >> + ? ? ? ?* Setup the Ref. clock frequency for the HAWK at 24 MHz. >> + ? ? ? ?*/ >> + ? ? ? cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); >> + ? ? ? cfgchip2 &= ~CFGCHIP2_REFFREQ; >> + ? ? ? cfgchip2 |= ?CFGCHIP2_REFFREQ_24MHZ; >> + ? ? ? __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); >> + >> + ? ? ? ret = gpio_request(DA850_USB1_VBUS_PIN, "USB1 VBUS\n"); >> + ? ? ? if (ret) { >> + ? ? ? ? ? ? ? printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 >> port " >> + ? ? ? ? ? ? ? ? ? ? ? "power control: %d\n", __func__, ret); > > ? pr_err() please. > >> + ? ? ? ? ? ? ? return; >> + ? ? ? } >> + ? ? ? gpio_direction_output(DA850_USB1_VBUS_PIN, 0); >> + >> + ? ? ? ret = gpio_request(DA850_USB1_OC_PIN, "USB1 OC"); >> + ? ? ? if (ret) { >> + ? ? ? ? ? ? ? printk(KERN_ERR "%s: failed to request GPIO for USB 1.1 >> port " >> + ? ? ? ? ? ? ? ? ? ? ? "over-current indicator: %d\n", __func__, ret); > > ? pr_err() please. > >> + ? ? ? ? ? ? ? return; >> + ? ? ? } >> + ? ? ? gpio_direction_input(DA850_USB1_OC_PIN); >> + >> + ? ? ? ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); >> + ? ? ? if (ret) { >> + ? ? ? ? ? ? ? pr_warning("%s: USB 1.1 registration failed: %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> + ? ? ? ? ? ? ? return; > > ? 'return' is useless here... Thanks for the feedback if I erase the return here I think I also have to erase the { ...} am I right ? Regards Victor Rodriguez >> + ? ? ? } >> +} >> + >> ?static struct davinci_uart_config omapl138_hawk_uart_config __initdata = >> { >> ? ? ? ?.enabled_uarts = 0x7, >> ?}; > > WBR, Sergei > From grant.likely at secretlab.ca Mon Oct 18 09:59:20 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Mon, 18 Oct 2010 08:59:20 -0600 Subject: [PATCH 01/12] misc: add driver for sequencer serial port In-Reply-To: <4CBC520B.9070502@ti.com> References: <1287081535-2864-1-git-send-email-cyril@ti.com> <1287081535-2864-2-git-send-email-cyril@ti.com> <20101016050055.GH21170@angua.secretlab.ca> <4CBC520B.9070502@ti.com> Message-ID: On Mon, Oct 18, 2010 at 7:56 AM, Cyril Chemparathy wrote: > Hi Grant, > > Thanks for the feedback, I will send out an updated v2 with the proposed > changes. > > [...] >>> +EXPORT_SYMBOL(ti_ssp_open); >> >> I'm not thrilled with the ti_ssp_open()/ti_ssp_close() usage model. >> It appears that the usage model is the board code registers an pile >> of platform_devices, one for the ssp, and one for each of the >> behaviours on top of it. ?Then the various driver instances have to >> figure out how to find each other and whether or not they are related. >> Am I correct? >> >> Rather than doing an end-run around the Linux driver model, I strongly >> recommend using the model to solve your problem. ?Register only the >> ssp platform_device in the board support code and pass it data about >> the intended behaviour (via platform data). ?When it gets probed, it >> can then register additional platform devices which will get probed by >> the requested driver. ?That way the specific ssp device instance data >> can be passed reliably to the spi/i2c/whatever driver without any >> ambiguity, without any uncertainty about whether a port is 'busy', and >> without the need of these open/close routines. >> >> (Hint: The trick is to set the platform_device's pdev->dev.parent >> pointer to make use of the Linux device model's hierarchy). > > I am not very thrilled with this approach either :-) ?I had looked at a > few other instances where something similar was being done (spi, i2c, > mdio, etc.), but felt that defining a new bus type would be an overkill > for this. Nope! you don't need to define a new bus type. Just continue to use platform bus. If you set the dev->parent pointer before registering the device then the device model with have the appropriate hierarchy. > For reference, could you please point me to some other place where > something similar is being done? Most of the multifunction devices operating in this way (though those implementations are probably more convoluted than they need to be. Take a look. If you still have trouble with it let me know and I'll draft an example for you. g. From vm.rod25 at gmail.com Mon Oct 18 11:00:19 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 18 Oct 2010 11:00:19 -0500 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <4CB88078.7050504@mvista.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-8-git-send-email-vm.rod25@gmail.com> <4CB88078.7050504@mvista.com> Message-ID: On Fri, Oct 15, 2010 at 11:25 AM, Sergei Shtylyov wrote: > Hello. > > On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds MMC/SD support for the Hawkboard-L138 system > >> Signed-off-by: Victor Rodriguez > > [...] > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index 6f76220..87dea28 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > [...] >> >> @@ -180,6 +208,28 @@ static __init void omapl138_hawk_init(void) >> ? ? ? ? ? ? ? ?pr_warning("%s: mcasp mux setup failed: %d\n", __func__, >> ret); >> ? ? ? ?da8xx_register_mcasp(0,&omapl138_hawk_snd_data); > > ? I'd put all the following into a sperate function. Thanks for the feedback Sergei I will fix that in a void function similar to omapl138_hawk_usb_init on the 9/9 patch >> + ? ? ? ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: MMC/SD0 mux setup failed: %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> + >> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: can not open GPIO %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_CD_PIN); >> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); > > ? You cannot call that if gpio_request{} failed. I think that is the idea. I am really confused here I have found in Documentation/gpio.txt that [...] Using GPIOs ----------- The first thing a system should do with a GPIO is allocate it, using the gpio_request() call; see later. One of the next things to do with a GPIO, often in board setup code when setting up a platform_device using the GPIO, is mark its direction: /* set as input or output, returning 0 or negative errno */ int gpio_direction_input(unsigned gpio); int gpio_direction_output(unsigned gpio, int value); ( ========== This is what I tried to implement ==================== ) The return value is zero for success, else a negative errno. It should be checked, since the get/set calls don't have error returns and since misconfiguration is possible. You should normally issue these calls from a task context. However, for spinlock-safe GPIOs it's OK to use them before tasking is enabled, as part of early board setup. [...] GPIO access that may sleep ** IN ADDITION ** calls to setup and configure such GPIOs must be made from contexts which may sleep, since they may need to access the GPIO controller chip too: (These setup calls are usually made from board setup or driver probe/teardown code, so this is an easy constraint.) gpio_direction_input() gpio_direction_output() gpio_request() ( ========== Here is my confusion it is a different order ==================== ) ## gpio_request_one() ## gpio_request_array() ## gpio_free_array() gpio_free() gpio_set_debounce() I think that you mean that I should not call gpio_direction_input if gpio_request failed am I right ? Regards Victor Rodriguez >> + ? ? ? ret = gpio_request(DA850_HAWK_MMCSD_WP_PIN, "MMC WP\n"); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: can not open GPIO %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, DA850_HAWK_MMCSD_WP_PIN); >> + ? ? ? gpio_direction_input(DA850_HAWK_MMCSD_WP_PIN); > > ? You cannot call that if gpio_request{} failed. > >> + ? ? ? ret = da8xx_register_mmcsd0(&da850_mmc_config); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: MMC/SD0 registration failed: %d\n", >> + ? ? ? ? ? ? ? ? ? ? ? __func__, ret); >> + >> ? ? ? ?ret = da8xx_register_watchdog(); >> ? ? ? ?if (ret) >> ? ? ? ? ? ? ? ?pr_warning("omapl138_hawk_init: " > > WBR, Sergei > From cyril at ti.com Mon Oct 18 14:25:10 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:10 -0400 Subject: [PATCH v2 00/12] tnetv107x ssp driver stack Message-ID: <1287429922-18870-1-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch series implements a driver stack that looks like the following: +--------+ | eeprom | . . . +--------+ +-----------+ +--------------+ +---------+ | regulator | . . . | i2c-gpio | | 1-wire | . . . +-----------+ +--------------+ +---------+ +----------------------+ +--------------------------------+ | ssp-spi | | ssp-gpio | +----------------------+ +--------------------------------+ +----------------------------------------------------------+ | ssp | +----------------------------------------------------------+ Changes between v1 and v2 of this series: - Replaced open()/close() semantics with dynamic platform_device registration on SSP probe. - Removed user-land interface to regulator registers - More sensible regulator constraints - Other minor cleanups Cyril Chemparathy (12): misc: add driver for sequencer serial port davinci: add tnetv107x ssp platform device davinci: add ssp config for tnetv107x evm board spi: add ti-ssp spi master driver davinci: add spi devices on tnetv107x evm regulator: add driver for tps6524x regulator davinci: add tnetv107x evm regulators gpio: add ti-ssp virtual gpio driver davinci: add tnetv107x evm ti-ssp gpio device backlight: add support for tps6116x controller davinci: add tnetv107x evm backlight device davinci: add tnetv107x evm i2c eeprom device arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ arch/arm/mach-davinci/devices-tnetv107x.c | 25 + arch/arm/mach-davinci/include/mach/ti_ssp.h | 99 ++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- drivers/gpio/Kconfig | 10 + drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 436 +++++++++++++++ drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 397 ++++++++++++++ drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++ 20 files changed, 2440 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/gpio/ti-ssp-gpio.c create mode 100644 drivers/misc/ti_ssp.c create mode 100644 drivers/regulator/tps6524x-regulator.c create mode 100644 drivers/spi/spi_ti_ssp.c create mode 100644 drivers/video/backlight/tps6116x.c From cyril at ti.com Mon Oct 18 14:25:12 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:12 -0400 Subject: [PATCH v2 02/12] davinci: add tnetv107x ssp platform device In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-3-git-send-email-cyril@ti.com> This patch adds an SSP platform device definition for the tnetv107x soc family. The clock lookup entry has also been updated to match. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 25 ++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index c9a86d8..2c7aa5f 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -35,6 +35,7 @@ #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 +#define TNETV107X_SSP_BASE 0x08088c00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 @@ -342,6 +343,25 @@ static struct platform_device tsc_device = { .resource = tsc_resources, }; +static struct resource ssp_resources[] = { + { + .start = TNETV107X_SSP_BASE, + .end = TNETV107X_SSP_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ssp_device = { + .name = "ti-ssp", + .id = -1, + .num_resources = ARRAY_SIZE(ssp_resources), + .resource = ssp_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -367,4 +387,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) keypad_device.dev.platform_data = info->keypad_config; platform_device_register(&keypad_device); } + + if (info->ssp_config) { + ssp_device.dev.platform_data = info->ssp_config; + platform_device_register(&ssp_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 5a681d8..c1df563 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -38,12 +38,14 @@ #include #include #include +#include struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ struct matrix_keypad_platform_data *keypad_config; + struct ti_ssp_data *ssp_config; }; extern struct platform_device tnetv107x_wdt_device; diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index daeae06..fcf30e7 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -277,7 +277,7 @@ static struct clk_lookup clks[] = { CLK(NULL, "timer1", &clk_timer1), CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm), CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp), - CLK("ti-ssp.0", NULL, &clk_ssp), + CLK("ti-ssp", NULL, &clk_ssp), CLK(NULL, "clk_tdm0", &clk_tdm0), CLK(NULL, "clk_vlynq", &clk_vlynq), CLK(NULL, "clk_mcdma", &clk_mcdma), -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:11 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:11 -0400 Subject: [PATCH v2 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-2-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch adds a driver for this controller device. The driver does not expose a user-land interface. Protocol drivers built on top of this layer are expected to remain in-kernel. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 89 ++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 436 +++++++++++++++++++++++++++ 4 files changed, 537 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/misc/ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h new file mode 100644 index 0000000..51afc42 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -0,0 +1,89 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TI_SSP_H__ +#define __TI_SSP_H__ + +struct ti_ssp_dev_data { + const char *dev_name; + unsigned long iosel; /* see note below */ + unsigned long config; + const void *pdata; + int pdata_sz; +}; + +struct ti_ssp_data { + unsigned long out_clock; + struct ti_ssp_dev_data dev_data[2]; +}; + +/* + * Sequencer port IO pin configuration bits. These do not correlate 1-1 with + * the hardware. The iosel field in the port data combines iosel1 and iosel2, + * and is therefore not a direct map to register space. It is best to use the + * macros below to construct iosel values. + * + * least significant 16 bits --> iosel1 + * most significant 16 bits --> iosel2 + */ + +#define SSP_IN 0x0000 +#define SSP_DATA 0x0001 +#define SSP_CLOCK 0x0002 +#define SSP_CHIPSEL 0x0003 +#define SSP_OUT 0x0004 +#define SSP_PIN_SEL(pin, v) ((v) << ((pin) * 3)) +#define SSP_PIN_MASK(pin) SSP_PIN_SEL(pin, 0x7) +#define SSP_INPUT_SEL(pin) ((pin) << 16) + +/* Sequencer port config bits */ +#define SSP_EARLY_DIN BIT(8) +#define SSP_DELAY_DOUT BIT(9) + +/* Sequence map definitions */ +#define SSP_CLK_HIGH BIT(0) +#define SSP_CLK_LOW 0 +#define SSP_DATA_HIGH BIT(1) +#define SSP_DATA_LOW 0 +#define SSP_CS_HIGH BIT(2) +#define SSP_CS_LOW 0 +#define SSP_OUT_MODE BIT(3) +#define SSP_IN_MODE 0 +#define SSP_DATA_REG BIT(4) +#define SSP_ADDR_REG 0 + +#define SSP_OPCODE_DIRECT ((0x0) << 5) +#define SSP_OPCODE_TOGGLE ((0x1) << 5) +#define SSP_OPCODE_SHIFT ((0x2) << 5) +#define SSP_OPCODE_BRANCH0 ((0x4) << 5) +#define SSP_OPCODE_BRANCH1 ((0x5) << 5) +#define SSP_OPCODE_BRANCH ((0x6) << 5) +#define SSP_OPCODE_STOP ((0x7) << 5) +#define SSP_BRANCH(addr) ((addr) << 8) +#define SSP_COUNT(cycles) ((cycles) << 8) + +int ti_ssp_raw_read(struct device *dev); +int ti_ssp_raw_write(struct device *dev, u32 val); +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len); +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output); +int ti_ssp_set_mode(struct device *dev, int mode); +int ti_ssp_set_iosel(struct device *dev, u32 iosel); + +#endif /* __TI_SSP_H__ */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..9fb8470 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -390,6 +390,17 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. +config TI_SSP + depends on ARCH_DAVINCI_TNETV107X + tristate "Sequencer Serial Port support" + default y + ---help--- + Say Y here if you want support for the Sequencer Serial Port + in a Texas Instruments TNETV107X SoC. + + To compile this driver as a module, choose M here: the + module will be called ti_ssp. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..7568100 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o +obj-$(CONFIG_TI_SSP) += ti_ssp.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o diff --git a/drivers/misc/ti_ssp.c b/drivers/misc/ti_ssp.c new file mode 100644 index 0000000..8249a8b --- /dev/null +++ b/drivers/misc/ti_ssp.c @@ -0,0 +1,436 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Register Offsets */ +#define REG_REV 0x00 +#define REG_IOSEL_1 0x04 +#define REG_IOSEL_2 0x08 +#define REG_PREDIV 0x0c +#define REG_INTR_ST 0x10 +#define REG_INTR_EN 0x14 +#define REG_TEST_CTRL 0x18 + +/* Per port registers */ +#define PORT_CFG_2 0x00 +#define PORT_ADDR 0x04 +#define PORT_DATA 0x08 +#define PORT_CFG_1 0x0c +#define PORT_STATE 0x10 + +#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) +#define SSP_PORT_CLKRATE_MASK 0x0f + +#define SSP_SEQRAM_WR_EN BIT(4) +#define SSP_SEQRAM_RD_EN BIT(5) +#define SSP_START BIT(15) +#define SSP_BUSY BIT(10) +#define SSP_PORT_ASL BIT(7) +#define SSP_PORT_CFO1 BIT(6) + +#define SSP_PORT_SEQRAM_SIZE 32 + +static const int ssp_port_base[] = {0x040, 0x080}; +static const int ssp_port_seqram[] = {0x100, 0x180}; + +struct ti_ssp { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; + struct clk *clk; + const struct ti_ssp_data *data; +}; + +#define dev2ssp(dev) dev_get_drvdata(dev->parent) +#define dev2port(dev) (to_platform_device(dev)->id) + +/* Register Access Helpers */ +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) +{ + return __raw_readl(ssp->regs + reg); +} + +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) +{ + __raw_writel(val, ssp->regs + reg); +} + +static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) +{ + u32 val = ssp_read(ssp, reg); + val &= ~mask; + val |= bits; + ssp_write(ssp, reg, val); +} + +static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg) +{ + return ssp_read(ssp, ssp_port_base[port] + reg); +} + +static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg, + u32 val) +{ + ssp_write(ssp, ssp_port_base[port] + reg, val); +} + +static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg, + u32 mask, u32 bits) +{ + ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits); +} + +static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, bits, 0); +} + +static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, 0, bits); +} + +static int __set_mode(struct ti_ssp *ssp, int port, int mode) +{ + mode &= SSP_PORT_CONFIG_MASK; + ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode); + + return 0; +} + +int ti_ssp_set_mode(struct device *dev, int mode) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_mode(ssp, port, mode); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_mode); + +static int __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) +{ + unsigned val; + + /* IOSEL1 gets the least significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_1); + val &= 0xffff << (port ? 0 : 16); + val |= (iosel & 0xffff) << (port ? 16 : 0); + ssp_write(ssp, REG_IOSEL_1, val); + + /* IOSEL2 gets the most significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_2); + val &= 0x0007 << (port ? 0 : 16); + val |= (iosel & 0x00070000) >> (port ? 0 : 16); + ssp_write(ssp, REG_IOSEL_2, val); + + return 0; +} + +int ti_ssp_set_iosel(struct device *dev, u32 iosel) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_iosel(ssp, port, iosel); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_iosel); + +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int i; + + if (len > SSP_PORT_SEQRAM_SIZE) + return -ENOSPC; + + spin_lock(&ssp->lock); + + /* Enable SeqRAM access */ + ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + /* Copy code */ + for (i = 0; i < len; i++) { + __raw_writel(prog[i], ssp->regs + offs + 4*i + + ssp_port_seqram[port]); + } + + /* Disable SeqRAM access */ + ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_load); + +int ti_ssp_raw_read(struct device *dev) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + u32 val; + + val = ssp_read(ssp, REG_IOSEL_2); + val >>= (port ? 27 : 11); + + return val & 0x0f; +} +EXPORT_SYMBOL(ti_ssp_raw_read); + +int ti_ssp_raw_write(struct device *dev, u32 val) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + u32 mask; + + spin_lock(&ssp->lock); + val &= 0x0f; + val <<= (port ? 22 : 6); + mask = 0x0f; + mask <<= (port ? 22 : 6); + ssp_rmw(ssp, REG_IOSEL_2, mask, val); + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_raw_write); + +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int count; + + if (pc & ~(0x3f)) + return -EINVAL; + + ssp_port_write(ssp, port, PORT_ADDR, input >> 16); + ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); + ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); + + ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); + + for (count = 10000; count; count--) { + if ((ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY) == 0) + break; + udelay(1); + } + + if (output) { + *(output) = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | + (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); + } + + if (!count) { + dev_err(ssp->dev, "timed out waiting for SSP operation\n"); + return -EIO; + } + + /* return stop address */ + return ssp_port_read(ssp, port, PORT_STATE) & 0x3f; +} +EXPORT_SYMBOL(ti_ssp_run); + +static int __unregister_subdev(struct device *dev, void *unused) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +static int unregister_subdevs(struct ti_ssp *ssp) +{ + return device_for_each_child(ssp->dev, NULL, __unregister_subdev); +} + +static void register_subdevs(struct ti_ssp *ssp) +{ + int id; + + for (id = 0; id < 2; id++) { + const struct ti_ssp_dev_data *data = &ssp->data->dev_data[id]; + + if (!data->dev_name) + continue; + + spin_lock(&ssp->lock); + __set_iosel(ssp, id, data->iosel); + ssp_port_rmw(ssp, id, PORT_CFG_1, SSP_PORT_CONFIG_MASK, + data->config); + ssp_port_rmw(ssp, id, PORT_CFG_2, SSP_PORT_CLKRATE_MASK, 0); + spin_unlock(&ssp->lock); + + platform_device_register_data(ssp->dev, data->dev_name, id, + data->pdata, data->pdata_sz); + } +} + +static int __devinit ti_ssp_probe(struct platform_device *pdev) +{ + static struct ti_ssp *ssp; + const struct ti_ssp_data *pdata = pdev->dev.platform_data; + int ret = 0, prediv = 0xff; + unsigned long sysclk; + struct device *dev = &pdev->dev; + + ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); + if (!ssp) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + ssp->data = pdata; + ssp->dev = dev; + dev_set_drvdata(dev, ssp); + + ret = -ENODEV; + ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ssp->res) { + dev_err(dev, "cannot determine register area\n"); + goto error_res; + } + + ret = -EINVAL; + if (!request_mem_region(ssp->res->start, resource_size(ssp->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + goto error_res; + } + + ret = -ENOMEM; + ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); + if (!ssp->regs) { + dev_err(dev, "cannot map register memory\n"); + goto error_map; + } + + ret = -EINVAL; + ssp->clk = clk_get(dev, NULL); + if (IS_ERR(ssp->clk)) { + dev_err(dev, "cannot claim device clock\n"); + goto error_clk; + } + + spin_lock_init(&ssp->lock); + + /* Power on and initialize SSP */ + ret = clk_enable(ssp->clk); + if (ret) + goto error_enable; + + /* Reset registers to a sensible known state */ + ssp_write(ssp, REG_IOSEL_1, 0); + ssp_write(ssp, REG_IOSEL_2, 0); + ssp_write(ssp, REG_INTR_EN, 0); + ssp_write(ssp, REG_TEST_CTRL, 0); + ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1); + ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1); + + sysclk = clk_get_rate(ssp->clk); + if (pdata && pdata->out_clock) + prediv = (sysclk / pdata->out_clock) - 1; + prediv = clamp(prediv, 0, 0xff); + ssp_rmw(ssp, REG_PREDIV, 0xff, prediv); + + register_subdevs(ssp); + + return 0; + +error_enable: + clk_put(ssp->clk); +error_clk: + iounmap(ssp->regs); +error_map: + release_mem_region(ssp->res->start, resource_size(ssp->res)); +error_res: + kfree(ssp); + return ret; +} + +static int __devexit ti_ssp_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ti_ssp *ssp = dev_get_drvdata(dev); + + unregister_subdevs(ssp); + clk_disable(ssp->clk); + clk_put(ssp->clk); + iounmap(ssp->regs); + release_mem_region(ssp->res->start, resource_size(ssp->res)); + kfree(ssp); + dev_set_drvdata(dev, NULL); + return 0; +} + +static struct platform_driver ti_ssp_driver = { + .probe = ti_ssp_probe, + .remove = __devexit_p(ti_ssp_remove), + .driver = { + .name = "ti-ssp", + .owner = THIS_MODULE, + } +}; + +static int __init ti_ssp_init(void) +{ + return platform_driver_register(&ti_ssp_driver); +} +arch_initcall_sync(ti_ssp_init); + +static void __exit ti_ssp_exit(void) +{ + platform_driver_unregister(&ti_ssp_driver); +} +module_exit(ti_ssp_exit); + +MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti_ssp"); -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:13 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:13 -0400 Subject: [PATCH v2 03/12] davinci: add ssp config for tnetv107x evm board In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-4-git-send-email-cyril@ti.com> This patch adds SSP configuration and pin muxing info for tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 5afa8fc..401ad26 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define EVM_MMC_WP_GPIO 21 @@ -99,6 +100,12 @@ static const short uart1_pins[] __initdata = { -1 }; +static const short ssp_pins[] __initdata = { + TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, + TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, + TNETV107X_SSP1_3, -1 +}; + static struct mtd_partition nand_partitions[] = { /* bootloader (U-Boot, etc) in first 12 sectors */ { @@ -196,17 +203,25 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static struct ti_ssp_data ssp_config = { + .out_clock = 250 * 1000, + .dev_data = { + }, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ .keypad_config = &keypad_config, + .ssp_config = &ssp_config, }; static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); davinci_cfg_reg_list(uart1_pins); + davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); } -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:14 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:14 -0400 Subject: [PATCH v2 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-5-git-send-email-cyril@ti.com> This patch adds an SPI master implementation that operates on top of an underlying TI-SSP port. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 5 + drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 397 +++++++++++++++++++++++++++ 4 files changed, 410 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi_ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 51afc42..63c88fe 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -34,6 +34,11 @@ struct ti_ssp_data { struct ti_ssp_dev_data dev_data[2]; }; +struct ti_ssp_spi_data { + int num_cs; + void (*select)(int cs); +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 91c2f4f..be86354 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -298,6 +298,13 @@ config SPI_STMP3XXX help SPI driver for Freescale STMP37xx/378x SoC SSP interface +config SPI_TI_SSP + tristate "TI SSP Controller SPI Driver" + depends on SPI_MASTER && TI_SSP + help + This selects an SPI master implementation using a TI sequencer + serial port. + config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e9cbd18..953aba7 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c new file mode 100644 index 0000000..a566158 --- /dev/null +++ b/drivers/spi/spi_ti_ssp.c @@ -0,0 +1,397 @@ +/* + * Sequencer Serial Port (SSP) based SPI master driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) + +struct ti_ssp_spi { + const struct ti_ssp_spi_data *pdata; + struct spi_master *master; + struct device *dev; + spinlock_t lock; + struct list_head msg_queue; + struct completion complete; + int shutdown:1; + struct workqueue_struct *workqueue; + struct work_struct work; + u8 mode, bpw; + int cs_active; + u32 pc_en, pc_dis, pc_wr, pc_rd; +}; + +static u32 do_read_data(struct ti_ssp_spi *hw) +{ + u32 ret; + + ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); + return ret; +} + +static void do_write_data(struct ti_ssp_spi *hw, u32 data) +{ + ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); +} + +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, + struct spi_transfer *t) +{ + int count; + + if (hw->bpw <= 8) { + u8 *rx = t->rx_buf; + const u8 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 1) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else if (hw->bpw <= 16) { + u16 *rx = t->rx_buf; + const u16 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 2) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else { + u32 *rx = t->rx_buf; + const u32 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 4) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } + + msg->actual_length += count; /* bytes transferred */ + + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, + hw->bpw, count, (count < t->len) ? " (under)" : ""); + + return (count < t->len) ? -EIO : 0; /* left over data */ +} + +static void chip_select(struct ti_ssp_spi *hw, int cs_active) +{ + cs_active = !!cs_active; + if (cs_active == hw->cs_active) + return; + ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); + hw->cs_active = cs_active; +} + +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) + +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) +{ + int error, idx = 0; + u32 seqram[16]; + u32 cs_en, cs_dis, clk; + u32 topbits, botbits; + + mode &= MODE_BITS; + if (mode == hw->mode && bpw == hw->bpw) + return 0; + + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; + + /* Construct instructions */ + + /* Disable Chip Select */ + hw->pc_dis = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; + + /* Enable Chip Select */ + hw->pc_en = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Reads and writes need to be split for bpw > 16 */ + topbits = (bpw > 16) ? 16 : bpw; + botbits = bpw - topbits; + + /* Write */ + hw->pc_wr = idx; + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; + if (botbits) + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Read */ + hw->pc_rd = idx; + if (botbits) + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + error = ti_ssp_load(hw->dev, 0, seqram, idx); + if (error < 0) + return error; + + error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? + 0 : SSP_EARLY_DIN)); + if (error < 0) + return error; + + hw->bpw = bpw; + hw->mode = mode; + + return error; +} + +static void ti_ssp_spi_work(struct work_struct *work) +{ + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); + + spin_lock_irq(&hw->lock); + + while (!list_empty(&hw->msg_queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + int status = 0; + + m = container_of(hw->msg_queue.next, struct spi_message, + queue); + + list_del_init(&m->queue); + + spi = m->spi; + + if (hw->pdata->select) + hw->pdata->select(spi->chip_select); + + list_for_each_entry(t, &m->transfers, transfer_list) { + int bpw = spi->bits_per_word; + int xfer_status; + + if (t->bits_per_word) + bpw = t->bits_per_word; + + if (setup_xfer(hw, bpw, spi->mode) < 0) + break; + + chip_select(hw, 1); + + spin_unlock_irq(&hw->lock); + + xfer_status = do_transfer(hw, m, t); + if (xfer_status < 0) + status = xfer_status; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + spin_lock_irq(&hw->lock); + + if (t->cs_change) + chip_select(hw, 0); + } + + chip_select(hw, 0); + m->status = status; + m->complete(m->context); + } + + if (hw->shutdown) + complete(&hw->complete); + + spin_unlock_irq(&hw->lock); +} + +static int ti_ssp_spi_setup(struct spi_device *spi) +{ + if (spi->bits_per_word > 32) + return -EINVAL; + + return 0; +} + +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) +{ + struct ti_ssp_spi *hw; + struct spi_transfer *t; + unsigned long flags; + int error = 0; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + hw = spi_master_get_devdata(spi->master); + + if (list_empty(&m->transfers) || !m->complete) + return -EINVAL; + + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->len && !(t->rx_buf || t->tx_buf)) { + dev_err(&spi->dev, "invalid xfer, no buffer\n"); + return -EINVAL; + } + + if (t->len && t->rx_buf && t->tx_buf) { + dev_err(&spi->dev, "invalid xfer, full duplex\n"); + return -EINVAL; + } + + if (t->bits_per_word > 32) { + dev_err(&spi->dev, "invalid xfer width %d\n", + t->bits_per_word); + return -EINVAL; + } + } + + spin_lock_irqsave(&hw->lock, flags); + if (hw->shutdown) { + error = -ESHUTDOWN; + goto error_unlock; + } + list_add_tail(&m->queue, &hw->msg_queue); + queue_work(hw->workqueue, &hw->work); +error_unlock: + spin_unlock_irqrestore(&hw->lock, flags); + return error; +} + +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) +{ + const struct ti_ssp_spi_data *pdata; + struct ti_ssp_spi *hw; + struct spi_master *master; + struct device *dev = &pdev->dev; + int error = 0; + + pdata = dev->platform_data; + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); + if (!master) { + dev_err(dev, "cannot allocate SPI master\n"); + return -ENOMEM; + } + + hw = spi_master_get_devdata(master); + platform_set_drvdata(pdev, hw); + + hw->master = master; + hw->dev = dev; + hw->pdata = pdata; + + spin_lock_init(&hw->lock); + init_completion(&hw->complete); + INIT_LIST_HEAD(&hw->msg_queue); + INIT_WORK(&hw->work, ti_ssp_spi_work); + + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); + if (!hw->workqueue) { + error = -ENOMEM; + dev_err(dev, "work queue creation failed\n"); + goto error_wq; + } + + master->bus_num = pdev->id; + master->num_chipselect = hw->pdata->num_cs; + master->mode_bits = MODE_BITS; + master->flags = SPI_MASTER_HALF_DUPLEX; + master->setup = ti_ssp_spi_setup; + master->transfer = ti_ssp_spi_transfer; + + error = spi_register_master(master); + if (error) { + dev_err(dev, "master registration failed\n"); + goto error_reg; + } + + return 0; + +error_reg: + destroy_workqueue(hw->workqueue); +error_wq: + spi_master_put(master); + return error; +} + +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) +{ + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); + int error; + + hw->shutdown = 1; + while (!list_empty(&hw->msg_queue)) { + error = wait_for_completion_interruptible(&hw->complete); + if (error < 0) { + hw->shutdown = 0; + return error; + } + } + destroy_workqueue(hw->workqueue); + spi_unregister_master(hw->master); + + return 0; +} + +static struct platform_driver ti_ssp_spi_driver = { + .probe = ti_ssp_spi_probe, + .remove = __devexit_p(ti_ssp_spi_remove), + .driver = { + .name = "ti-ssp-spi", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_spi_init(void) +{ + return platform_driver_register(&ti_ssp_spi_driver); +} +subsys_initcall(ti_ssp_spi_init); + +static void __exit ti_ssp_spi_exit(void) +{ + platform_driver_unregister(&ti_ssp_spi_driver); +} +module_exit(ti_ssp_spi_exit); + +MODULE_DESCRIPTION("SSP SPI Master"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spi_ti_ssp"); -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:21 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:21 -0400 Subject: [PATCH v2 11/12] davinci: add tnetv107x evm backlight device In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-12-git-send-email-cyril@ti.com> The tnetv107x evm board has a backlight device that is connected on one of the SSP ports. This patch adds the board definitions necessary to plug the backlight driver to the GPIO corresponding to this SSP pin. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 270ba26..ca61f8a 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -45,6 +45,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) { @@ -360,6 +361,12 @@ static struct spi_board_info spi_info[] __initconst = { }, }; +static struct platform_device backlight_device = { + .name = "tps6116x", + .id = -1, + .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -368,6 +375,8 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); + platform_device_register(&backlight_device); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:22 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:22 -0400 Subject: [PATCH v2 12/12] davinci: add tnetv107x evm i2c eeprom device In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-13-git-send-email-cyril@ti.com> The tnetv107x evm board has an I2C device connected on one of the SSP ports. This patch adds board definitions for a GPIO based I2C master, as well as definitions for the eeprom device on these boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 30 +++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index ca61f8a..8b94a63 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include @@ -45,6 +48,8 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_I2C_SDA_GPIO (SSP_GPIO_START + 0) +#define EVM_I2C_SCL_GPIO (SSP_GPIO_START + 1) #define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) @@ -367,6 +372,29 @@ static struct platform_device backlight_device = { .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, }; +struct i2c_gpio_platform_data i2c_data = { + .sda_pin = EVM_I2C_SDA_GPIO, + .scl_pin = EVM_I2C_SCL_GPIO, +}; + +static struct platform_device i2c_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &i2c_data, +}; + +static struct at24_platform_data at24_config = { + .byte_len = SZ_16K / 8, + .page_size = 16, +}; + +static struct i2c_board_info i2c_info[] __initconst = { + { + I2C_BOARD_INFO("24c16", 0x50), + .platform_data = &at24_config, + }, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -376,8 +404,10 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); platform_device_register(&backlight_device); + platform_device_register(&i2c_device); spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:15 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:15 -0400 Subject: [PATCH v2 05/12] davinci: add spi devices on tnetv107x evm In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-6-git-send-email-cyril@ti.com> This patch adds definitions for spi devices on the tnetv107x evm platform. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 45 +++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 401ad26..c37c5c6 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 +#define EVM_SPI_CS_GPIO 54 static int initialize_gpio(int gpio, char *desc) { @@ -203,9 +205,47 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static void spi_select_device(int cs) +{ + static int gpio; + + if (!gpio) { + int ret; + ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel"); + if (ret < 0) { + pr_err("cannot open spi chipsel gpio\n"); + gpio = -ENOSYS; + return; + } else { + gpio = EVM_SPI_CS_GPIO; + gpio_direction_output(gpio, 0); + } + } + + if (gpio < 0) + return; + + return gpio_set_value(gpio, cs ? 1 : 0); +} + +static const struct ti_ssp_spi_data spi_master_data = { + .num_cs = 2, + .select = spi_select_device, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [1] = { + .dev_name = "ti-ssp-spi", + .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | + SSP_PIN_SEL(1, SSP_DATA) | + SSP_PIN_SEL(2, SSP_CHIPSEL) | + SSP_PIN_SEL(3, SSP_IN) | + SSP_INPUT_SEL(3), + .pdata = &spi_master_data, + .pdata_sz = sizeof(spi_master_data), + }, }, }; @@ -217,6 +257,9 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct spi_board_info spi_info[] __initconst = { +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -224,6 +267,8 @@ static __init void tnetv107x_evm_board_init(void) davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); + + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:18 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:18 -0400 Subject: [PATCH v2 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-9-git-send-email-cyril@ti.com> This patch adds a GPIO driver based on TI's SSP device. This driver does not support GPIO-IRQs. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 4 + drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/ti-ssp-gpio.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 63c88fe..21f1429 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -39,6 +39,10 @@ struct ti_ssp_spi_data { void (*select)(int cs); }; +struct ti_ssp_gpio_data { + int start; +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..e400761 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -111,6 +111,16 @@ config GPIO_SCH This driver can also be built as a module. If so, the module will be called sch-gpio. +config GPIO_TI_SSP + tristate "TI SSP Controller GPIO Driver" + depends on GPIOLIB && TI_SSP + help + Say yes here to support a virtual GPIO interface on TI SSP ports. + Each SSP port translates into 4 GPIOs, with no IRQ support. + + This driver can also be built as a module. If so, the module + will be called ti-ssp-gpio. + comment "I2C GPIO expanders:" config GPIO_MAX7300 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..98b4551 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c new file mode 100644 index 0000000..c046713 --- /dev/null +++ b/drivers/gpio/ti-ssp-gpio.c @@ -0,0 +1,200 @@ +/* + * Sequencer Serial Port (SSP) based virtual GPIO driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ti_ssp_gpio { + struct gpio_chip chip; +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) + struct device *dev; + spinlock_t lock; + u8 out; + u32 iosel; +}; + +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error = 0; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + spin_unlock(&gpio->lock); + + return error; +} + +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + if (error < 0) + goto error; + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + error = ti_ssp_raw_write(gpio->dev, gpio->out); + +error: + spin_unlock(&gpio->lock); + return error; +} + +static int value_get(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int ret; + + spin_lock(&gpio->lock); + + ret = ti_ssp_raw_read(gpio->dev); + if (ret >= 0) + ret = (ret & BIT(gpio_num)) ? 1 : 0; + + spin_unlock(&gpio->lock); + return ret; +} + +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + + spin_lock(&gpio->lock); + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + ti_ssp_raw_write(gpio->dev, gpio->out); + + spin_unlock(&gpio->lock); +} + +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) +{ + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct ti_ssp_gpio *gpio; + int error; + + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(dev, "cannot allocate driver data\n"); + return -ENOMEM; + } + + gpio->dev = dev; + gpio->iosel = SSP_PIN_SEL(0, SSP_IN) | SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | SSP_PIN_SEL(3, SSP_IN); + spin_lock_init(&gpio->lock); + platform_set_drvdata(pdev, gpio); + + gpio->chip.base = pdata->start; + gpio->chip.ngpio = 4; + gpio->chip.dev = &pdev->dev; + gpio->chip.label = "ti_ssp_gpio"; + gpio->chip.owner = THIS_MODULE; + gpio->chip.get = value_get; + gpio->chip.set = value_set; + gpio->chip.direction_input = direction_in; + gpio->chip.direction_output = direction_out; + + error = gpiochip_add(&gpio->chip); + if (error < 0) { + dev_err(dev, "gpio chip registration failed (%d)\n", error); + goto error; + } + + dev_info(dev, "ssp gpio interface registered\n"); + return 0; + +error: + kfree(gpio); + return error; +} + +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) +{ + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); + int error; + + error = gpiochip_remove(&gpio->chip); + if (error < 0) + return error; + kfree(gpio); + return 0; +} + +static struct platform_driver ti_ssp_gpio_driver = { + .probe = ti_ssp_gpio_probe, + .remove = __devexit_p(ti_ssp_gpio_remove), + .driver = { + .name = "ti-ssp-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_gpio_init(void) +{ + return platform_driver_register(&ti_ssp_gpio_driver); +} +subsys_initcall(ti_ssp_gpio_init); + +static void __exit ti_ssp_gpio_exit(void) +{ + platform_driver_unregister(&ti_ssp_gpio_driver); +} +module_exit(ti_ssp_gpio_exit); + +MODULE_DESCRIPTION("GPIO interface for TI-SSP"); +MODULE_AUTHOR("Cyril Chemparathy "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti-ssp-gpio"); -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:17 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:17 -0400 Subject: [PATCH v2 07/12] davinci: add tnetv107x evm regulators In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-8-git-send-email-cyril@ti.com> This patch adds regulator and spi board info definitions for the tps6524x power management IC found on tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 85 +++++++++++++++++++++++++++ 1 files changed, 85 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index c37c5c6..d4c3d18 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -257,7 +260,89 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct regulator_consumer_supply usb_consumers[] = { + REGULATOR_SUPPLY("vbus", "musb_hdrc.1"), +}; + +static struct regulator_consumer_supply lcd_consumers[] = { + REGULATOR_SUPPLY("vlcd", "tps6116x"), +}; + +static struct regulator_init_data regulators[] = { + { + .constraints = { + .name = "DCDC1", + .min_uV = 1000000, + .max_uV = 1000000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC2", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC3", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 4800000, + .max_uV = 4800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(usb_consumers), + .consumer_supplies = usb_consumers, + .constraints = { + .name = "USB", + .min_uA = 200000, + .max_uA = 1000000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | + REGULATOR_CHANGE_STATUS, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(lcd_consumers), + .consumer_supplies = lcd_consumers, + .constraints = { + .name = "LCD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, +}; + static struct spi_board_info spi_info[] __initconst = { + { + .modalias = "tps6524x", + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + .platform_data = regulators, + }, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:19 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:19 -0400 Subject: [PATCH v2 09/12] davinci: add tnetv107x evm ti-ssp gpio device In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-10-git-send-email-cyril@ti.com> This patch adds definitions to hook up one of the ti-ssp ports to the SSP GPIO driver. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index d4c3d18..270ba26 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -40,6 +40,8 @@ #include #include +#define SSP_GPIO_START 128 + #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 @@ -236,9 +238,22 @@ static const struct ti_ssp_spi_data spi_master_data = { .select = spi_select_device, }; +static const struct ti_ssp_gpio_data ssp_gpio_data = { + .start = SSP_GPIO_START, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [0] = { + .dev_name = "ti-ssp-gpio", + .iosel = SSP_PIN_SEL(0, SSP_IN) | + SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | + SSP_PIN_SEL(3, SSP_IN), + .pdata = &ssp_gpio_data, + .pdata_sz = sizeof(ssp_gpio_data), + }, [1] = { .dev_name = "ti-ssp-spi", .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:16 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:16 -0400 Subject: [PATCH v2 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-7-git-send-email-cyril@ti.com> TPS6524X provides three step-down converters and two general-purpose LDO voltage regulators. This device is interfaced using SPI. Signed-off-by: Cyril Chemparathy --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++++++++++ 3 files changed, 703 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/tps6524x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 172951b..7875c2e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -235,5 +235,15 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. +config REGULATOR_TPS6524X + tristate "TI TPS6524X Power regulators" + depends on TI_SSP + help + This driver supports TPS6524X voltage regulator chips. TPS6524X + provides three step-down converters and two general-purpose LDO + voltage regulators. This device is interfaced using a customized + serial interface currently supported on the sequencer serial + port controller. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 8285fd8..a8e5bc0 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c new file mode 100644 index 0000000..6d6cc5e --- /dev/null +++ b/drivers/regulator/tps6524x-regulator.c @@ -0,0 +1,692 @@ +/* + * Regulator driver for TPS6524x PMIC + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_LDO_SET 0x0 +#define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */ +#define LDO_VSEL_MASK 0x0f +#define LDO2_ILIM_SHIFT 12 +#define LDO2_VSEL_SHIFT 4 +#define LDO1_ILIM_SHIFT 8 +#define LDO1_VSEL_SHIFT 0 + +#define REG_BLOCK_EN 0x1 +#define BLOCK_MASK 1 +#define BLOCK_LDO1_SHIFT 0 +#define BLOCK_LDO2_SHIFT 1 +#define BLOCK_LCD_SHIFT 2 +#define BLOCK_USB_SHIFT 3 + +#define REG_DCDC_SET 0x2 +#define DCDC_VDCDC_MASK 0x1f +#define DCDC_VDCDC1_SHIFT 0 +#define DCDC_VDCDC2_SHIFT 5 +#define DCDC_VDCDC3_SHIFT 10 + +#define REG_DCDC_EN 0x3 +#define DCDCDCDC_EN_MASK 0x1 +#define DCDCDCDC1_EN_SHIFT 0 +#define DCDCDCDC1_PG_MSK BIT(1) +#define DCDCDCDC2_EN_SHIFT 2 +#define DCDCDCDC2_PG_MSK BIT(3) +#define DCDCDCDC3_EN_SHIFT 4 +#define DCDCDCDC3_PG_MSK BIT(5) + +#define REG_USB 0x4 +#define USB_ILIM_SHIFT 0 +#define USB_ILIM_MASK 0x3 +#define USB_TSD_SHIFT 2 +#define USB_TSD_MASK 0x3 +#define USB_TWARN_SHIFT 4 +#define USB_TWARN_MASK 0x3 +#define USB_IWARN_SD BIT(6) +#define USB_FAST_LOOP BIT(7) + +#define REG_ALARM 0x5 +#define ALARM_LDO1 BIT(0) +#define ALARM_DCDC1 BIT(1) +#define ALARM_DCDC2 BIT(2) +#define ALARM_DCDC3 BIT(3) +#define ALARM_LDO2 BIT(4) +#define ALARM_USB_WARN BIT(5) +#define ALARM_USB_ALARM BIT(6) +#define ALARM_LCD BIT(9) +#define ALARM_TEMP_WARM BIT(10) +#define ALARM_TEMP_HOT BIT(11) +#define ALARM_NRST BIT(14) +#define ALARM_POWERUP BIT(15) + +#define REG_INT_ENABLE 0x6 +#define INT_LDO1 BIT(0) +#define INT_DCDC1 BIT(1) +#define INT_DCDC2 BIT(2) +#define INT_DCDC3 BIT(3) +#define INT_LDO2 BIT(4) +#define INT_USB_WARN BIT(5) +#define INT_USB_ALARM BIT(6) +#define INT_LCD BIT(9) +#define INT_TEMP_WARM BIT(10) +#define INT_TEMP_HOT BIT(11) +#define INT_GLOBAL_EN BIT(15) + +#define REG_INT_STATUS 0x7 +#define STATUS_LDO1 BIT(0) +#define STATUS_DCDC1 BIT(1) +#define STATUS_DCDC2 BIT(2) +#define STATUS_DCDC3 BIT(3) +#define STATUS_LDO2 BIT(4) +#define STATUS_USB_WARN BIT(5) +#define STATUS_USB_ALARM BIT(6) +#define STATUS_LCD BIT(9) +#define STATUS_TEMP_WARM BIT(10) +#define STATUS_TEMP_HOT BIT(11) + +#define REG_SOFTWARE_RESET 0xb +#define REG_WRITE_ENABLE 0xd +#define REG_REV_ID 0xf + +#define N_DCDC 3 +#define N_LDO 2 +#define N_SWITCH 2 +#define N_REGULATORS (3 /* DCDC */ + \ + 2 /* LDO */ + \ + 2 /* switch */) + +#define FIXED_ILIMSEL BIT(0) +#define FIXED_VOLTAGE BIT(1) + +#define CMD_READ(reg) ((reg) << 6) +#define CMD_WRITE(reg) (BIT(5) | (reg) << 6) +#define STAT_CLK BIT(3) +#define STAT_WRITE BIT(2) +#define STAT_INVALID BIT(1) +#define STAT_WP BIT(0) + +struct field { + int reg; + int shift; + int mask; +}; + +struct supply_info { + const char *name; + int n_voltages; + const int *voltages; + int fixed_voltage; + int n_ilimsels; + const int *ilimsels; + int fixed_ilimsel; + int flags; + struct field enable, voltage, ilimsel; +}; + +struct tps6524x { + struct device *dev; + struct spi_device *spi; + struct mutex lock; + struct regulator_desc desc[N_REGULATORS]; + struct regulator_dev *rdev[N_REGULATORS]; +}; + +static int __read_reg(struct tps6524x *hw, int reg) +{ + int error = 0; + u16 cmd = CMD_READ(reg), in; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = ∈ + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "read reg %d, data %x, status %x\n", + reg, in, status); + + if (!(status & STAT_CLK) || (status & STAT_WRITE)) + return -EIO; + + if (status & STAT_INVALID) + return -EINVAL; + + return in; +} + +static int read_reg(struct tps6524x *hw, int reg) +{ + int ret; + + mutex_lock(&hw->lock); + ret = __read_reg(hw, reg); + mutex_unlock(&hw->lock); + + return ret; +} + +static int __write_reg(struct tps6524x *hw, int reg, int val) +{ + int error = 0; + u16 cmd = CMD_WRITE(reg), out = val; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = &out; + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n", + reg, out, status); + + if (!(status & STAT_CLK) || !(status & STAT_WRITE)) + return -EIO; + + if (status & (STAT_INVALID | STAT_WP)) + return -EINVAL; + + return error; +} + +static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + ret = __read_reg(hw, reg); + if (ret < 0) + return ret; + + ret &= ~mask; + ret |= val; + + ret = __write_reg(hw, reg, ret); + + return (ret < 0) ? ret : 0; +} + +static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + mutex_lock(&hw->lock); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 1); + if (ret) { + dev_err(hw->dev, "failed to set write enable\n"); + goto error; + } + + ret = __rmw_reg(hw, reg, mask, val); + if (ret) + dev_err(hw->dev, "failed to rmw register %d\n", reg); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 0); + if (ret) { + dev_err(hw->dev, "failed to clear write enable\n"); + goto error; + } + +error: + mutex_unlock(&hw->lock); + + return ret; +} + +static int read_field(struct tps6524x *hw, const struct field *field) +{ + int tmp; + + tmp = read_reg(hw, field->reg); + if (tmp < 0) + return tmp; + + return (tmp >> field->shift) & field->mask; +} + +static int write_field(struct tps6524x *hw, const struct field *field, + int val) +{ + if (val & ~field->mask) + return -EOVERFLOW; + + return rmw_protect(hw, field->reg, + field->mask << field->shift, + val << field->shift); +} + +static const int dcdc1_voltages[] = { + 800000, 825000, 850000, 875000, + 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, + 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, + 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, + 1500000, 1525000, 1550000, 1575000, +}; + +static const int dcdc2_voltages[] = { + 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, + 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, + 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, + 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, +}; + +static const int dcdc3_voltages[] = { + 2400000, 2450000, 2500000, 2550000, 2600000, + 2650000, 2700000, 2750000, 2800000, 2850000, + 2900000, 2950000, 3000000, 3050000, 3100000, + 3150000, 3200000, 3250000, 3300000, 3350000, + 3400000, 3450000, 3500000, 3550000, 3600000, +}; + +static const int ldo1_voltages[] = { + 4300000, 4350000, 4400000, 4450000, + 4500000, 4550000, 4600000, 4650000, + 4700000, 4750000, 4800000, 4850000, + 4900000, 4950000, 5000000, 5050000, +}; + +static const int ldo2_voltages[] = { + 1100000, 1150000, 1200000, 1250000, + 1300000, 1700000, 1750000, 1800000, + 1850000, 1900000, 3150000, 3200000, + 3250000, 3300000, 3350000, 3400000, +}; + +static const int ldo_ilimsel[] = { + 400000, 1500000 +}; + +static const int usb_ilimsel[] = { + 200000, 400000, 800000, 1000000 +}; + +#define __MK_FIELD(_reg, _mask, _shift) \ + { .reg = (_reg), .mask = (_mask), .shift = (_shift), } + +static const struct supply_info supply_info[N_REGULATORS] = { + { + .name = "DCDC1", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc1_voltages), + .voltages = dcdc1_voltages, + .fixed_ilimsel = 2400000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC1_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC1_SHIFT), + }, + { + .name = "DCDC2", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc2_voltages), + .voltages = dcdc2_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC2_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC2_SHIFT), + }, + { + .name = "DCDC3", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc3_voltages), + .voltages = dcdc3_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC3_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC3_SHIFT), + }, + { + .name = "LDO1", + .n_voltages = ARRAY_SIZE(ldo1_voltages), + .voltages = ldo1_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO1_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO1_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO1_ILIM_SHIFT), + }, + { + .name = "LDO2", + .n_voltages = ARRAY_SIZE(ldo2_voltages), + .voltages = ldo2_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO2_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO2_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO2_ILIM_SHIFT), + }, + { + .name = "USB", + .flags = FIXED_VOLTAGE, + .fixed_voltage = 5000000, + .n_ilimsels = ARRAY_SIZE(usb_ilimsel), + .ilimsels = usb_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_USB_SHIFT), + .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK, + USB_ILIM_SHIFT), + }, + { + .name = "LCD", + .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, + .fixed_voltage = 5000000, + .fixed_ilimsel = 400000, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LCD_SHIFT), + }, +}; + +static int list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return selector ? -EINVAL : info->fixed_voltage; + + if (selector < 0 || selector >= info->n_voltages) + return -EINVAL; + + return info->voltages[selector]; +} + +static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return -EINVAL; + + for (i = 0; i < info->n_voltages; i++) + if (min_uV <= info->voltages[i] && + max_uV >= info->voltages[i]) + break; + + if (i >= info->n_voltages) + return -EINVAL; + + return write_field(hw, &info->voltage, i); +} + +static int get_voltage(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return info->fixed_voltage; + + ret = read_field(hw, &info->voltage); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_voltages)) + return -EIO; + + return info->voltages[ret]; +} + +static int set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return -EINVAL; + + for (i = 0; i < info->n_ilimsels; i++) + if (min_uA <= info->ilimsels[i] && + max_uA >= info->ilimsels[i]) + break; + + if (i >= info->n_ilimsels) + return -EINVAL; + + return write_field(hw, &info->ilimsel, i); +} + +static int get_current_limit(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return info->fixed_ilimsel; + + ret = read_field(hw, &info->ilimsel); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_ilimsels)) + return -EIO; + + return info->ilimsels[ret]; +} + +static int enable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 1); +} + +static int disable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 0); +} + +static int is_supply_enabled(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return read_field(hw, &info->enable); +} + +static struct regulator_ops regulator_ops = { + .is_enabled = is_supply_enabled, + .enable = enable_supply, + .disable = disable_supply, + .get_voltage = get_voltage, + .set_voltage = set_voltage, + .list_voltage = list_voltage, + .set_current_limit = set_current_limit, + .get_current_limit = get_current_limit, +}; + +static int __devexit pmic_remove(struct spi_device *spi) +{ + struct tps6524x *hw = spi_get_drvdata(spi); + int i; + + if (!hw) + return 0; + for (i = 0; i < N_REGULATORS; i++) { + if (hw->rdev[i]) + regulator_unregister(hw->rdev[i]); + hw->rdev[i] = NULL; + } + spi_set_drvdata(spi, NULL); + kfree(hw); + return 0; +} + +static int __devinit pmic_probe(struct spi_device *spi) +{ + struct tps6524x *hw; + struct device *dev = &spi->dev; + const struct supply_info *info = supply_info; + struct regulator_init_data *init_data; + int ret = 0, i; + + init_data = dev->platform_data; + if (!init_data) { + dev_err(dev, "could not find regulator platform data\n"); + return -EINVAL; + } + + hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); + if (!hw) { + dev_err(dev, "cannot allocate regulator private data\n"); + return -ENOMEM; + } + spi_set_drvdata(spi, hw); + + memset(hw, 0, sizeof(struct tps6524x)); + hw->dev = dev; + hw->spi = spi_dev_get(spi); + mutex_init(&hw->lock); + + for (i = 0; i < N_REGULATORS; i++, info++, init_data++) { + hw->desc[i].name = info->name; + hw->desc[i].id = i; + hw->desc[i].n_voltages = info->n_voltages; + hw->desc[i].ops = ®ulator_ops; + hw->desc[i].type = REGULATOR_VOLTAGE; + hw->desc[i].owner = THIS_MODULE; + + if (info->flags & FIXED_VOLTAGE) + hw->desc[i].n_voltages = 1; + + hw->rdev[i] = regulator_register(&hw->desc[i], dev, + init_data, hw); + if (IS_ERR(hw->rdev[i])) { + ret = PTR_ERR(hw->rdev[i]); + hw->rdev[i] = NULL; + goto fail; + } + } + + return 0; + +fail: + pmic_remove(spi); + return ret; +} + +static struct spi_driver pmic_driver = { + .probe = pmic_probe, + .remove = __devexit_p(pmic_remove), + .driver = { + .name = "tps6524x", + .owner = THIS_MODULE, + }, +}; + +static int __init pmic_driver_init(void) +{ + return spi_register_driver(&pmic_driver); +} +subsys_initcall_sync(pmic_driver_init); + +static void __exit pmic_driver_exit(void) +{ + spi_unregister_driver(&pmic_driver); +} +module_exit(pmic_driver_exit); + +MODULE_DESCRIPTION("TPS6524X PMIC Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:tps6524x"); -- 1.7.0.4 From cyril at ti.com Mon Oct 18 14:25:20 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Mon, 18 Oct 2010 15:25:20 -0400 Subject: [PATCH v2 10/12] backlight: add support for tps6116x controller In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <1287429922-18870-11-git-send-email-cyril@ti.com> TPS6116x is an EasyScale backlight controller device. This driver supports TPS6116x devices connected on a single GPIO. Signed-off-by: Cyril Chemparathy --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+), 1 deletions(-) create mode 100644 drivers/video/backlight/tps6116x.c diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index e54a337..06e868e 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -307,6 +307,13 @@ config BACKLIGHT_PCF50633 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to enable its driver. +config BACKLIGHT_TPS6116X + tristate "TPS6116X LCD Backlight" + depends on GENERIC_GPIO + help + This driver controls the LCD backlight level for EasyScale capable + SSP connected backlight controllers. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 44c0f81..5d407c8 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -35,4 +35,4 @@ obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o - +obj-$(CONFIG_BACKLIGHT_TPS6116X)+= tps6116x.o diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c new file mode 100644 index 0000000..7a9f8ca --- /dev/null +++ b/drivers/video/backlight/tps6116x.c @@ -0,0 +1,340 @@ +/* + * TPS6116X LCD Backlight Controller Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS6116X_MAX_INTENSITY 31 +#define TPS6116X_DEFAULT_INTENSITY 10 + +/* Easyscale timing w/ margin (usecs) */ +#define T_POWER_SETTLE 2000 +#define T_ES_DELAY 120 +#define T_ES_DETECT 280 +#define T_ES_WINDOW (1000 - T_ES_DELAY - T_ES_DETECT) +#define T_START 3 +#define T_EOS 3 +#define T_INACTIVE 3 +#define T_ACTIVE (3 * T_INACTIVE) + +#define CMD_SET 0x72 + +struct tps6116x { + struct ti_ssp_device *handle; + struct device *dev; + int gpio, gpio_initialized; + struct mutex lock; + int intensity; + int power; + struct backlight_properties props; + struct backlight_device *bl; + int suspended:1; + struct regulator *regulator; +}; + +static int __set_power(struct tps6116x *hw, int power) +{ + unsigned long flags; + int error; + + power = !!power; + if (power == hw->power) + return 0; /* nothing to do */ + + /* disabling is simple... choke power */ + if (!power) { + error = regulator_disable(hw->regulator); + goto done; + } + + /* set ctrl pin init state for easyscale detection */ + gpio_set_value(hw->gpio, 0); + + error = regulator_enable(hw->regulator); + if (error < 0) + goto done; + + udelay(T_POWER_SETTLE); + + /* + * Now that the controller is powered up, we need to put it into 1-wire + * mode. This is a timing sensitive operation, hence the irq disable. + * Ideally, this should happen rarely, and mostly at init, so disabling + * interrupts for the duration should not be a problem. + */ + local_irq_save(flags); + + gpio_set_value(hw->gpio, 1); + udelay(T_ES_DELAY); + gpio_set_value(hw->gpio, 0); + udelay(T_ES_DETECT); + gpio_set_value(hw->gpio, 1); + + local_irq_restore(flags); + +done: + if (error >= 0) + hw->power = power; + + return error; +} + +static void __write_byte(struct tps6116x *hw, u8 data) +{ + int bit; + + gpio_set_value(hw->gpio, 1); + udelay(T_START); + + for (bit = 0; bit < 8; bit++, data <<= 1) { + int val = data & 0x80; + int t_lo = val ? T_INACTIVE : T_ACTIVE; + int t_hi = val ? T_ACTIVE : T_INACTIVE; + + gpio_set_value(hw->gpio, 0); + udelay(t_lo); + gpio_set_value(hw->gpio, 1); + udelay(t_hi); + } + + gpio_set_value(hw->gpio, 0); + udelay(T_EOS); + gpio_set_value(hw->gpio, 1); +} + +static void __set_intensity(struct tps6116x *hw, int intensity) +{ + unsigned long flags; + + intensity = clamp(intensity, 0, TPS6116X_MAX_INTENSITY); + + local_irq_save(flags); + __write_byte(hw, CMD_SET); + __write_byte(hw, intensity); + local_irq_restore(flags); +} + +static int set_intensity(struct tps6116x *hw, int intensity) +{ + int error = 0; + + if (intensity == hw->intensity) + return 0; + + mutex_lock(&hw->lock); + + if (!hw->gpio_initialized) { + error = gpio_request_one(hw->gpio, GPIOF_DIR_OUT, + dev_name(hw->dev)); + if (error < 0) + goto error; + hw->gpio_initialized = 1; + } + + error = __set_power(hw, intensity ? 1 : 0); + if (error < 0) + goto error; + + if (intensity > 0) + __set_intensity(hw, intensity); + + hw->intensity = intensity; +error: + mutex_unlock(&hw->lock); + + return error; +} + +static ssize_t intensity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "%d\n", hw->intensity); + + return len; +} + +static ssize_t intensity_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + unsigned long intensity; + int error; + + error = strict_strtoul(buf, 10, &intensity); + if (error < 0) + return error; + + error = set_intensity(hw, intensity); + if (error < 0) + return error; + + return count; +} + +DEVICE_ATTR(intensity, S_IWUSR | S_IRUGO, intensity_show, intensity_store); + +static int get_brightness(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + + return hw->intensity; +} + +static int update_status(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + int intensity = bl->props.brightness; + + if (hw->suspended) + intensity = 0; + if (bl->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + return set_intensity(hw, intensity); +} + +static const struct backlight_ops tps6116x_backlight_ops = { + .get_brightness = get_brightness, + .update_status = update_status, +}; + +static int __devinit tps6116x_probe(struct platform_device *pdev) +{ + struct tps6116x *hw; + struct device *dev = &pdev->dev; + struct backlight_properties props; + int error; + + hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL); + if (!hw) { + error = -ENOMEM; + dev_err(dev, "cannot allocate driver data\n"); + goto fail0; + } + platform_set_drvdata(pdev, hw); + + memset(hw, 0, sizeof(struct tps6116x)); + hw->gpio = (int)dev->platform_data; + hw->dev = dev; + + mutex_init(&hw->lock); + + error = device_create_file(dev, &dev_attr_intensity); + if (error < 0) { + dev_err(dev, "cannot create device attributes\n"); + goto fail1; + } + + hw->regulator = regulator_get(dev, "vlcd"); + if (IS_ERR(hw->regulator)) { + error = PTR_ERR(hw->regulator); + dev_err(dev, "cannot claim regulator\n"); + goto fail2; + } + + memset(&props, 0, sizeof(props)); + props.max_brightness = TPS6116X_MAX_INTENSITY; + props.brightness = TPS6116X_DEFAULT_INTENSITY; + + hw->bl = backlight_device_register("tps6116x", hw->dev, hw, + &tps6116x_backlight_ops, &props); + if (IS_ERR(hw->bl)) { + error = PTR_ERR(hw->bl); + dev_err(dev, "backlight registration failed\n"); + goto fail3; + } + + dev_info(dev, "registered backlight controller\n"); + return 0; + +fail3: + regulator_put(hw->regulator); +fail2: + device_remove_file(dev, &dev_attr_intensity); +fail1: + kfree(hw); + platform_set_drvdata(pdev, NULL); +fail0: + return error; +} + +static int __devexit tps6116x_remove(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + + backlight_device_unregister(hw->bl); + regulator_disable(hw->regulator); + regulator_put(hw->regulator); + device_remove_file(hw->dev, &dev_attr_intensity); + kfree(hw); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int tps6116x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 1; + update_status(hw->bl); + return 0; +} + +static int tps6116x_resume(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 0; + update_status(hw->bl); + return 0; +} + +static struct platform_driver tps6116x_driver = { + .probe = tps6116x_probe, + .remove = __devexit_p(tps6116x_remove), + .suspend = tps6116x_suspend, + .resume = tps6116x_resume, + .driver = { + .name = "tps6116x", + .owner = THIS_MODULE, + }, +}; + +static int __init tps6116x_init(void) +{ + return platform_driver_register(&tps6116x_driver); +} +module_init(tps6116x_init); + +static void __exit tps6116x_exit(void) +{ + platform_driver_unregister(&tps6116x_driver); +} +module_exit(tps6116x_exit); + +MODULE_DESCRIPTION("SSP TPS6116X Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tps6116x"); -- 1.7.0.4 From vm.rod25 at gmail.com Mon Oct 18 18:56:39 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 18 Oct 2010 18:56:39 -0500 Subject: [PATCH v4 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <4CB880EC.3000909@mvista.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> <1287112105-11968-9-git-send-email-vm.rod25@gmail.com> <4CB880EC.3000909@mvista.com> Message-ID: On Fri, Oct 15, 2010 at 11:27 AM, Sergei Shtylyov wrote: > Hello. > > On 10/15/10 07:08, vm.rod25 at gmail.com wrote: > >> From: Victor Rodriguez > >> This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system > >> Signed-off-by: Victor Rodriguez > > [...] > >> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c >> index 4458bff..2a4730e 100644 >> --- a/arch/arm/mach-davinci/da850.c >> +++ b/arch/arm/mach-davinci/da850.c >> @@ -345,6 +345,20 @@ static struct clk aemif_clk = { >> ? ? ? ?.flags ? ? ? ? ?= ALWAYS_ENABLED, >> ?}; >> >> +static struct clk usb11_clk = { >> + ? ? ? .name ? ? ? ? ? = "usb11", >> + ? ? ? .parent ? ? ? ? =&pll0_sysclk4, >> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB11, >> + ? ? ? .gpsc ? ? ? ? ? = 1, >> + ? ? ? }; > > ? This } should be at the start of line. > >> + >> +static struct clk usb20_clk = { >> + ? ? ? .name ? ? ? ? ? = "usb20", >> + ? ? ? .parent ? ? ? ? =&pll0_sysclk2, >> + ? ? ? .lpsc ? ? ? ? ? = DA8XX_LPSC1_USB20, >> + ? ? ? .gpsc ? ? ? ? ? = 1, >> + ? ? ? }; > > ? Same comment. > > WBR, Sergei > Thanks for the feedback i appreciate a lot i have already do this change If there is any other change i think I could send the v5 do you agree ? Thanks Sincerely yours Victor Rodriguez From vm.rod25 at gmail.com Mon Oct 18 18:58:14 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 18 Oct 2010 18:58:14 -0500 Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <4CB88082.5080901@mvista.com> References: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> <4CB73AD5.2060907@mvista.com> <4CB88082.5080901@mvista.com> Message-ID: On Fri, Oct 15, 2010 at 11:25 AM, Sergei Shtylyov wrote: > Hello. > > On 10/15/10 01:44, Victor Rodriguez wrote: > >>>> From: Victor Rodriguez > >>>> This patch adds EMAC support for the Hawkboard-L138 system > >>>> Signed-off-by: Victor Rodriguez > > [...] > >>>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> index c472dd8..3ae5178 100644 >>>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>>> @@ -19,6 +19,53 @@ >>>> >>>> ?#include >>>> ?#include >>>> +#include >>>> + >>>> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? ? "0:07" >>>> + >>>> +static short omapl138_hawk_mii_pins[] __initdata = { >>>> + ? ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >>>> + ? ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, >>>> DA850_MII_RXER, >>>> + ? ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >>>> + ? ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, >>>> DA850_MDIO_CLK, >>>> + ? ? ? DA850_MDIO_D, >>>> + ? ? ? -1 >>>> +}; >>>> + >>>> +static int __init omapl138_hawk_config_emac(void) >>>> +{ >>>> + ? ? ? void __iomem *cfgchip3; >>>> + ? ? ? int ret; >>>> + ? ? ? u32 val; >>>> + ? ? ? struct davinci_soc_info *soc_info =&davinci_soc_info; >>>> + >>>> + ? ? ? if (!machine_is_omapl138_hawkboard()) >>>> + ? ? ? ? ? ? ? return 0; >>>> + >>>> + ? ? ? cfgchip3 = DA8XSYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > >>> ? Could be initializer... > >> I do not understand this > > ? I mean you could assign 'cfgchip3' right when you declare it. > >>>> + ? ? ? val = __raw_readl(cfgchip3); >>>> + >>>> + ? ? ? val&= ~BIT(8); >>>> + ? ? ? ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); >>>> + ? ? ? pr_info("EMAC: MII PHY configured\n"); > >>> ? I think this pr_info() should follow __raw_writel() call. > >> Ok > >>>> + ? ? ? if (ret) >>>> + ? ? ? ? ? ? ? pr_warning("%s: " >>>> + ? ? ? ? ? ? ? ? ? ? ? "cpgmac/mii mux setup failed: %d\n", __func__, >>>> ret); > >>> ? You should return here. > >>>> + >>>> + ? ? ? /* configure the CFGCHIP3 register for MII */ >>>> + ? ? ? __raw_writel(val, cfgchip3); >>>> + >>>> + ? ? ? soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; >>>> + >>>> + ? ? ? ret = da8xx_register_emac(); >>>> + ? ? ? if (ret) >>>> + ? ? ? ? ? ? ? pr_warning("%s: " >>>> + ? ? ? ? ? ? ? ? ? ? ? "emac registration failed: %d\n", __func__, >>>> ret); >>>> + ? ? ? return 0; > >>> ? Why this function returns anything at all if it'a always 0, and the >>> result >>> is ignored? > >>>> @@ -30,6 +77,8 @@ static __init void omapl138_hawk_init(void) >>>> >>>> ? ? ? ?davinci_serial_init(&omapl138_hawk_uart_config); > >>>> + ? ? ? ret = omapl138_hawk_config_emac(); >>> >>> ? Why assign 'ret', if you're ignoring the result? > >> Sorry my mistake I ?forgot to check this, please check the nest patch >> maybe it is a better implementation > > [...] > >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >> b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index c472dd8..35bcea1 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -19,6 +19,53 @@ >> >> ?#include >> ?#include >> +#include >> + >> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? ? "0:07" >> + >> +static short omapl138_hawk_mii_pins[] __initdata = { >> + ? ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >> + ? ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >> + ? ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >> + ? ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >> + ? ? ? DA850_MDIO_D, >> + ? ? ? -1 >> +}; >> + >> +static __init void omapl138_hawk_config_emac(void) >> +{ >> + ? ? ? void __iomem *cfgchip3; >> + ? ? ? int ret; >> + ? ? ? u32 val; >> + ? ? ? struct davinci_soc_info *soc_info =&davinci_soc_info; >> + >> + ? ? ? if (!machine_is_omapl138_hawkboard()) >> + ? ? ? ? ? ? ? ? ? ? ? return; >> + >> + ? ? ? cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); >> + >> + ? ? ? val = __raw_readl(cfgchip3); >> + >> + ? ? ? val&= ~BIT(8); >> + ? ? ? ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: " >> + ? ? ? ? ? ? ? ? ? ? ? "cpgmac/mii mux setup failed: %d\n", __func__, >> ret); >> + ? ? ? ? ? ? ? ? ? ? ? return; > > ? Should enclose these two statements in {} and fix indentation. > >> + >> + ? ? ? /* configure the CFGCHIP3 register for MII */ >> + ? ? ? __raw_writel(val, cfgchip3); >> + ? ? ? pr_info("EMAC: MII PHY configured\n"); >> + >> + ? ? ? soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; >> + >> + ? ? ? ret = da8xx_register_emac(); >> + ? ? ? if (ret) >> + ? ? ? ? ? ? ? pr_warning("%s: " >> + ? ? ? ? ? ? ? ? ? ? ? "emac registration failed: %d\n", __func__, ret); >> + ? ? ? ? ? ? ? ? ? ? ? return; > > ? 'return' is useless here, and it should've been enclosed into {}... > > WBR. Sergei > Hi Sergei Thanks a lot for your feed back I have already fixed Regards Victor Rodriguez From broonie at opensource.wolfsonmicro.com Mon Oct 18 19:22:12 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Mon, 18 Oct 2010 17:22:12 -0700 Subject: [PATCH v2 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287429922-18870-7-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-7-git-send-email-cyril@ti.com> Message-ID: <20101019002212.GC27248@opensource.wolfsonmicro.com> On Mon, Oct 18, 2010 at 03:25:16PM -0400, Cyril Chemparathy wrote: > TPS6524X provides three step-down converters and two general-purpose LDO > voltage regulators. This device is interfaced using SPI. > > Signed-off-by: Cyril Chemparathy Acked-by: Mark Brown From Jon.Povey at racelogic.co.uk Mon Oct 18 20:16:06 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Tue, 19 Oct 2010 02:16:06 +0100 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44E@Cloud.RL.local> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > I think that you mean that I should not call gpio_direction_input if > gpio_request failed am I right ? Yes, if gpio_request() fails that means you have not claimed that gpio, something else is using it already or it's not available due to other misconfiguration. So you shouldn't be trying to set its direction or anything like that. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From vm.rod25 at gmail.com Mon Oct 18 20:50:56 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Mon, 18 Oct 2010 20:50:56 -0500 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44E@Cloud.RL.local> References: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44E@Cloud.RL.local> Message-ID: On Mon, Oct 18, 2010 at 8:16 PM, Jon Povey wrote: > davinci-linux-open-source-bounces at linux.davincidsp.com wrote: >> I think that you mean that I should not call gpio_direction_input if >> gpio_request failed am I right ? > > Yes, if gpio_request() fails that means you have not claimed that gpio, > something else is using it already or it's not available due to other > misconfiguration. > > So you shouldn't be trying to set its direction or anything like that. > > -- > Jon Povey > jon.povey at racelogic.co.uk > > Racelogic is a limited company registered in England. Registered number 2743719 . > Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . > > The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network > > > Hi Jon Yes you are right and as I understand gpio_request will give a 0 if it success and because of that the warning never will appear, if there is a problem there will be a -1 and the warning will be printed. I could fix this with a return that breaks the code like this ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); if (ret) { pr_warning("%s: can not open GPIO %d\n", __func__, DA850_HAWK_MMCSD_CD_PIN); return; } gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); Is this ok ? Thanks Sincerely yours Victor Rodriguez From Jon.Povey at racelogic.co.uk Mon Oct 18 20:54:13 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Tue, 19 Oct 2010 02:54:13 +0100 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44F@Cloud.RL.local> Victor Rodriguez wrote: > On Mon, Oct 18, 2010 at 8:16 PM, Jon Povey > wrote: >> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: >>> I think that you mean that I should not call gpio_direction_input if >>> gpio_request failed am I right ? >> >> Yes, if gpio_request() fails that means you have not claimed that >> gpio, something else is using it already or it's not available due >> to other misconfiguration. >> >> So you shouldn't be trying to set its direction or anything like >> that. > Yes you are right and as I understand gpio_request will give a 0 if it > success and because of that the warning never will appear, if there is > a problem there will be a -1 and the warning will be printed. I could > fix this with a return that breaks the code like this > > ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); > if (ret) { pr_warning("%s: can not open GPIO %d\n", > __func__, DA850_HAWK_MMCSD_CD_PIN); > return; } > gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); > > Is this ok ? I haven't seen the rest of your code to tell if that is OK, but not calling any other gpio_* functions if the request fails is the right idea. You may need to do more cleanup to gracefuly handle the failure, like returning an error value at least. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From sumeshkkn at hotmail.com Tue Oct 19 00:15:34 2010 From: sumeshkkn at hotmail.com (Sumesh Kaana) Date: Tue, 19 Oct 2010 05:15:34 +0000 Subject: Firewire on dm6467 Message-ID: Hi there, I am using dm6467 based custom board. i have a firewire chip sitting on the PCI bus.After enabling the PCI support in the kernel , i could list the following entry when lspci executed. ## lspci00:08.0 Class 0c00: 104c:8026 I have a requirement to use Networking over firewire, so following are enabled on the menuconfig CONFIG_IEEE1394CONFIG_IEEE1394_OHCI1394CONFIG_IEEE1394_RAWIOCONFIG_IEEE1394_ETH1394 when the board boots up, ifconfig shows the following: #ifconfig eth0eth0 Link encap:UNSPEC HWaddr 00-30-8D-01-20-C0-95-8D-00-00-00-00-00-00-00-00 inet addr:172.16.1.57 Bcast:172.16.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) but tried to ping to any PC, it does not ping. after some time of debugging i came to know that PCI Host on default EVMs cannot receive PCI interrupts ( http://processors.wiki.ti.com/index.php/DaVinci_PSP_3.02_Linux_Installation_User_Guide#PCI_Host_Driver_Known_Issues ), i connected the the PCI interrupt line to one of the GPIO interrupt lines. (GPIO0 - 48 ). and in the pci-dm646x.c following are changed: int dm646x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin){ /* * Standard EVM doesn't have any dedicated lines connected to PCI * Interrupts. */ return 48; // testing added by xxxxx , GPIO line 48 return -1;} kernel boot log as follows: Linux version 2.6.32-rc2-davinci1final (root at ieee) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #763 PREEMPT Mon Oct 18 19:05:32 IST 2010CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177CPU: VIVT data cache, VIVT instruction cacheMachine: DaVinci DM646x EVMMemory policy: ECC disabled, Data cache writebackOn node 0 totalpages: 65536free_area_init_node: node 0, pgdat c0d16dd4, node_mem_map c8000000 DMA zone: 256 pages used for memmap DMA zone: 0 pages reserved DMA zone: 32512 pages, LIFO batch:7 Normal zone: 256 pages used for memmap Normal zone: 32512 pages, LIFO batch:7DaVinci dm6467_rev3.x variant 0x1Built 1 zonelists in Zone order, mobility grouping on. Total pages: 65024Kernel command line: console=ttyS0,115200n8 ip=dhcpPID hash table entries: 1024 (order: 0, 4096 bytes)Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)Memory: 256MB = 256MB totalMemory: 246044KB available (3304K code, 307K data, 9936K init, 0K highmem)SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1Hierarchical RCU implementation.NR_IRQS:245Console: colour dummy device 80x30Calibrating delay loop... 181.86 BogoMIPS (lpj=909312)Mount-cache hash table entries: 512CPU: Testing write buffer coherency: okDaVinci: 43 gpio irqsNET: Registered protocol family 16MUX: Setting register STSOMUX_DISABLE PINMUX0 (0x00000000) = 0x00040000 -> 0x00040000MUX: Setting register STSIMUX_DISABLE PINMUX0 (0x00000000) = 0x00040000 -> 0x00040000MUX: initialized PTSOMUX_DISABLEMUX: Setting register PTSOMUX_DISABLE PINMUX0 (0x00000000) = 0x00040000 -> 0x00000000MUX: Setting register PTSIMUX_DISABLE PINMUX0 (0x00000000) = 0x00000000 -> 0x00000000@@@@@@ UART 0@@@@@@ UART 1@@@@@@ UART 2MUX: initialized HPI32ENMUX: Setting register HPI32EN PINMUX0 (0x00000000) = 0x00000000 -> 0x00000002MUX: initialized PCIENMUX: Setting register PCIEN PINMUX0 (0x00000000) = 0x00000002 -> 0x00000004Driver Reg with 0bio: create slab at 0vgaarb: loadedSCSI subsystem initializedSwitching to clocksource timer0_1Switched to high resolution mode on CPU 0 musb_hdrc: USB Peripheral mode controller at fec64000 using PIO, IRQ 13Driver Reg with 0NET: Registered protocol family 2IP route cache hash table entries: 2048 (order: 1, 8192 bytes)TCP established hash table entries: 8192 (order: 4, 65536 bytes)TCP bind hash table entries: 8192 (order: 3, 32768 bytes)TCP: Hash tables configured (established 8192 bind 8192)TCP reno registeredNET: Registered protocol family 1RPC: Registered udp transport module.RPC: Registered tcp transport module.RPC: Registered tcp NFSv4.1 backchannel transport module. PCI DM646x :dm646x_pci_initPCI: bootcfg = 0x106, bootmode = 0x6PCI: Invoking PCI BIOS...PCI: Enabling Clock...PCI: Setting up Host Controller...PCI: Starting PCI scan... nr = 0PCI: Scanning bus 0000:00pci 0000:00:08.0: found [104c:8026] class 000c00 header type 00pci 0000:00:08.0: reg 10 32bit mmio: [0x000000-0x0007ff]pci 0000:00:08.0: reg 14 32bit mmio: [0x000000-0x003fff]pci 0000:00:08.0: calling pci_fixup_ide_bases+0x0/0x50pci 0000:00:08.0: calling quirk_resource_alignment+0x0/0x1a4pci 0000:00:08.0: calling quirk_usb_early_handoff+0x0/0x560pci 0000:00:08.0: supports D1 D2pci 0000:00:08.0: PME# supported from D0 D1 D2 D3hotpci 0000:00:08.0: PME# disabledPCI: Fixups for bus 0000:00PCI: bus0: Fast back to back transfers disabledPCI: Bus scan for 0000:00 returning with max=00PCI: 0000:00:08.0 swizzling pin 1 => pin 1 slot 8PCI: 0000:00:08.0 mapping slot 8 pin 1 => irq 48pci 0000:00:08.0: fixup irq: got 48PCI: Assigning IRQ 48 to 0000:00:08.0pci 0000:00:08.0: BAR 1: got res [0x30000000-0x30003fff] bus [0x30000000-0x30003fff] flags 0x20200pci 0000:00:08.0: BAR 1: moved to bus [0x30000000-0x30003fff] flags 0x20200pci 0000:00:08.0: BAR 0: got res [0x30004000-0x300047ff] bus [0x30004000-0x300047ff] flags 0x20200pci 0000:00:08.0: BAR 0: moved to bus [0x30004000-0x300047ff] flags 0x20200msgmni has been set to 481io scheduler noop registeredio scheduler anticipatory registered (default)pci 0000:00:08.0: calling quirk_cardbus_legacy+0x0/0x38Serial: 8250/16550 driver, 3 ports, IRQ sharing disabledserial8250.0: ttyS0 at MMIO 0x1c20000 (irq = 40) is a ST16654console [ttyS0] enabledserial8250.0: ttyS1 at MMIO 0x1c20400 (irq = 41) is a ST16654serial8250.0: ttyS2 at MMIO 0x1c20800 (irq = 42) is a ST16654brd: module loadedloop: module loadedat24 1-0050: 32768 byte 24c256 EEPROM (writable)Read MAC addr from EEPROM: ff:ff:ff:ff:ff:ff spi_davinci spi_davinci.0: DaVinci SPI driver in EDMA modeUsing RX channel = 17 , TX channel = 16 and event queue = 3spi_davinci spi_davinci.0: registered master spi0spi spi0.1: setup mode 0, 8 bits/w, 750000 Hz max --> 0spi_davinci spi_davinci.0: registered child spi0.1spi_davinci spi_davinci.0: Controller at 0xfec66800Driver Reg with 0PPP generic driver version 2.4.2PPP Deflate Compression module registeredtun: Universal TUN/TAP device driver, 1.6tun: (C) 1999-2004 Max Krasnyansky console [netcon0] enablednetconsole: network logging started DEBUG : ohci1394_pci_probePCI: enabling device 0000:00:08.0 (0140 -> 0142)ohci1394 0000:00:08.0: enabling bus masteringohci1394: fw-host0: Remapped memory spaces reg 0xd0814000ohci1394: fw-host0: SelfID buffer ff001000 is not aligned on 8Kb boundary... may cause problems on some CXD3222 chipohci1394: fw-host0: Soft reset finishedohci1394: fw-host0: Iso contexts reg: 000000a8 implemented: 0000000fohci1394: fw-host0: Iso contexts reg: 00000098 implemented: 000000ff DEBUG : PCI_INTERRUPT_LINE: 48,retval:0ohci1394: fw-host0: Receive DMA ctx=0 initializedohci1394: fw-host0: Receive DMA ctx=0 initializedohci1394: fw-host0: Transmit DMA ctx=0 initializedohci1394: fw-host0: Transmit DMA ctx=1 initializedohci1394: fw-host0: physUpperBoundOffset=00000000ohci1394: fw-host0: OHCI-1394 1.1 (PCI): IRQ=[48] MMIO=[30004000-300047ff] Max Packet=[2048] IR/IT contexts=[4/8]ieee1394: CSR: setting expire to 10, HZ=100ieee1394: raw1394: /dev/raw1394 device initialized eth1394: eth0: IPv4 over IEEE 1394 (fw-host0)ohci1394: fw-host0: ohci_iso_recv_init: packet-per-buffer mode, DMA buffer is 16 pages (65536 bytes), using 16 blocks, buf_stride 4096, block_irq_interval 1mice: PS/2 mouse device common for all micei2c /dev entries driverTCP cubic registeredNET: Registered protocol family 10NET: Registered protocol family 17Clocks: disable unused mcasp0Clocks: disable unused mcasp1Clocks: disable unused emacClocks: disable unused timer1Clocks: disable unused idedavinci_emac_probe: using random MAC addr: be:b6:99:c7:3a:57emac-mii: probedbase address : 0x1c80000mdio_register successfullProbe Device Not Found ieee1394: send packet at S200: 0200dfa0ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Starting transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000.ieee1394: send packet at S200: 0200dfa0ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0 Freeing init memory: 9936KDSPLINK Module (1.65.00.02) created on Date: Oct 5 2010 Time: 11:43:58eth1: no IPv6 routers present# when i tried to ping following prints are got from kernel: # ping 172.16.1.55PING 172.16.1.55 (172.16.1.55): 56 data bytesohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000 // IntEventSet registerohci1394: fw-host0: OHCI_BASE+84 0x00020000 // IntEventClearohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000ohci1394: fw-host0: Inserting packet for node 0-63:1023, tlabel=0, tcode=0xa, speed=1ohci1394: fw-host0: Waking transmit DMA ctx=0ohci1394: fw-host0: OHCI_BASE+80 0x04520000ohci1394: fw-host0: OHCI_BASE+84 0x00020000 --- 172.16.1.55 ping statistics ---7 packets transmitted, 0 packets received, 100% packet loss I guess no interrupts are received by the driver,no prints form the irq handler are printed.when observed /proc/interrupts the firewire driver received NO interrupts. any idea why this can be? is there any other known issue for PCI on davinci?? or am i missing something? is my interrupt setting correct?any suggestion would be great help. Thanks,Sumesh. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cyril at ti.com Tue Oct 19 06:02:55 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 19 Oct 2010 07:02:55 -0400 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: References: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44E@Cloud.RL.local> Message-ID: <4CBD7ADF.8020405@ti.com> Hi Victor, [...] > Yes you are right and as I understand gpio_request will give a 0 if it > success and because of that the warning never will appear, if there is > a problem there will be a -1 and the warning will be printed. I could > fix this with a return that breaks the code like this > > ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); > if (ret) { > pr_warning("%s: can not open GPIO %d\n", > __func__, DA850_HAWK_MMCSD_CD_PIN); > return; > } > gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); I think gpio_request_one() is simpler. This requests the gpio and sets it up: ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, GPIOF_DIR_IN, "MMC CD"); if (ret < 0) { ... failed ... } Regards Cyril. From vm.rod25 at gmail.com Tue Oct 19 12:15:45 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Tue, 19 Oct 2010 12:15:45 -0500 Subject: [PATCH v4 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <4CBD7ADF.8020405@ti.com> References: <70E876B0EA86DD4BAF101844BC814DFE093EEAB44E@Cloud.RL.local> <4CBD7ADF.8020405@ti.com> Message-ID: On Tue, Oct 19, 2010 at 6:02 AM, Cyril Chemparathy wrote: > Hi Victor, > > [...] >> Yes you are right and as I understand gpio_request will give a 0 if it >> success and because of that the warning never will appear, if there is >> a problem there will be a -1 and the warning will be printed. I could >> fix this with a return that breaks the code like this >> >> ? ? ? ?ret = gpio_request(DA850_HAWK_MMCSD_CD_PIN, "MMC CD\n"); >> ? ? ? ?if (ret) { >> ? ? ? ? ? ? ? ?pr_warning("%s: can not open GPIO %d\n", >> ? ? ? ? ? ? ? ? ? ? ? ?__func__, DA850_HAWK_MMCSD_CD_PIN); >> ? ? ? ? ? ? ? ?return; >> ? ? ? ?} >> ? ? ? ?gpio_direction_input(DA850_HAWK_MMCSD_CD_PIN); > > I think gpio_request_one() is simpler. ?This requests the gpio and sets > it up: > > ? ? ? ?ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? GPIOF_DIR_IN, "MMC CD"); > ? ? ? ?if (ret < 0) { > ? ? ? ? ? ? ? ?... failed ... > ? ? ? ?} > > Regards > Cyril. > Thanks works perfect Regards Victor Rodriguez From vm.rod25 at gmail.com Tue Oct 19 13:06:18 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:18 -0500 Subject: [PATCH v5 0/9] Add Omapl138-Hawkboard support Message-ID: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (9): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard davinci: ASoC support for Omapl138-Hawkboard davinci: McASP configuration for Omapl138-Hawkboard davinci: Audio support for Omapl138-Hawkboard davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboar davinci: USB clocks for Omapl138-Hawkboard davinci: USB1.1 support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 317 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 22 ++- arch/arm/mach-davinci/include/mach/mux.h | 4 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 349 insertions(+), 5 deletions(-) From vm.rod25 at gmail.com Tue Oct 19 13:06:20 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:20 -0500 Subject: [PATCH v5 2/9] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-3-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 54 +++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 8633245..ef3974e 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -64,6 +64,55 @@ static __init void omapl138_hawk_config_emac(void) __func__, ret); } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -77,6 +126,11 @@ static __init void omapl138_hawk_init(void) omapl138_hawk_config_emac(); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("%s: EDMA registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:19 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:19 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 47 +++++++++++++++++++++++++++ 1 files changed, 47 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..8633245 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,51 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static __init void omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + if (!machine_is_omapl138_hawkboard()) + return; + + val = __raw_readl(cfgchip3); + + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + if (ret) { + pr_warning("%s: cpgmac/mii mux setup failed: %d\n", + __func__, ret); + return; + } + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + pr_info("EMAC: MII PHY configured\n"); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: emac registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +75,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:21 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:21 -0500 Subject: [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..72c6752 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ + MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:24 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:24 -0500 Subject: [PATCH v5 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-7-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration to enable MMC/SD and USB-OHCI on the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 4 ++++ arch/arm/mach-davinci/include/mach/mux.h | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..4458bff 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -543,11 +543,15 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false) MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false) /* GPIO function */ + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false) MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false) MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..5d4e0fe 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -908,11 +908,15 @@ enum davinci_da850_index { DA850_NEMA_CS_2, /* GPIO function */ + DA850_GPIO2_4, DA850_GPIO2_6, DA850_GPIO2_8, DA850_GPIO2_15, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:22 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:22 -0500 Subject: [PATCH v5 4/9] davinci: McASP configuration for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-5-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration for MacASP used on the Hawkboard-L138 system in order to add Audio support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:23 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:23 -0500 Subject: [PATCH v5 5/9] davinci: Audio support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-6-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 46 +++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ef3974e..97836e9 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,38 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci Hawkboard audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -131,6 +164,19 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: EDMA registration failed: %d\n", __func__, ret); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("%s: i2c0 registration failed: %d\n", + __func__, ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:26 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:26 -0500 Subject: [PATCH v5 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-9-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 4458bff..b3b1adb 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,20 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, +}; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, +}; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +401,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:27 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:27 -0500 Subject: [PATCH v5 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-10-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB pen drive In order to connect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 107 +++++++++++++++++++++++++++ 1 files changed, 107 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c83050b..1531717 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -208,6 +211,108 @@ static __init void omapl138_hawk_mmc_init(void) __func__, ret); } +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; + +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + pr_err(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) { + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + return; + } + + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request_one(DA850_USB1_VBUS_PIN, + GPIOF_DIR_OUT, "USB1 VBUS"); + if (ret < 0) { + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + + ret = gpio_request_one(DA850_USB1_OC_PIN, + GPIOF_DIR_IN, "USB1 OC"); + if (ret < 0) { + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -240,6 +345,8 @@ static __init void omapl138_hawk_init(void) omapl138_hawk_mmc_init(); + omapl138_hawk_usb_init(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From vm.rod25 at gmail.com Tue Oct 19 13:06:25 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Tue, 19 Oct 2010 13:06:25 -0500 Subject: [PATCH v5 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287511587-22216-8-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 63 +++++++++++++++++++++++++++ 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 97836e9..c83050b 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define HAWKBOARD_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -147,6 +149,65 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static __init void omapl138_hawk_mmc_init(void) +{ + int ret; + + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) { + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, + GPIOF_DIR_IN, "MMC CD"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN, + GPIOF_DIR_IN, "MMC WP"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + return; + } + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -177,6 +238,8 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + omapl138_hawk_mmc_init(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.6.0.5 From Jeff.Graham at brukeroptics.com Tue Oct 19 13:23:16 2010 From: Jeff.Graham at brukeroptics.com (Jeff Graham) Date: Tue, 19 Oct 2010 14:23:16 -0400 Subject: SPI support, kernel stability Message-ID: Hello list, I need to use SPI onboard the dm3730 to talk to an external piece of hardware. The dm3730+linux side would be the slave. I have a TI dm3730 evaluation kit (TMDEXVM3730) that is built by Mistral. The kit comes with the DVSDK 4_00_00_17 and seems based on the Arago distribution 2010.05. The Linux kernel is 2.6.32. >From a brief look at this list, there is a lot of recent activity with SPI in the git tree, so I have several questions: 1) Is the kernel in the git tree stable enough? 2) Does the SPI code in my current kernel work for my needs? Support does not seem to be configured, so I will have to reconfigure and compile it. 3) Does the git kernel make improvements to SPI (and other omap/davinci items) worth switching to? Thanks, Jeff From renegs.2378 at gmail.com Tue Oct 19 15:38:22 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Tue, 19 Oct 2010 15:38:22 -0500 Subject: How to reply a tested by for a patch Message-ID: Hi all, I'm very new in kernel stuffs so; I have applied a set of patches for a hawkboard-L138 and I wonder if there is specific format for reply a tested by. Should I add comments about the way I tested or just I reply it by adding a "tested by" headline? Thanks & regards, Rene. -------------- next part -------------- An HTML attachment was scrubbed... URL: From grant.likely at secretlab.ca Wed Oct 20 10:22:16 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Wed, 20 Oct 2010 09:22:16 -0600 Subject: [PATCH v2 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287429922-18870-2-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-2-git-send-email-cyril@ti.com> Message-ID: <20101020152216.GA7285@angua.secretlab.ca> On Mon, Oct 18, 2010 at 03:25:11PM -0400, Cyril Chemparathy wrote: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > This patch adds a driver for this controller device. The driver does not > expose a user-land interface. Protocol drivers built on top of this layer are > expected to remain in-kernel. > > Signed-off-by: Cyril Chemparathy I like this version much better. Acked-by: Grant Likely From grant.likely at secretlab.ca Wed Oct 20 10:23:43 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Wed, 20 Oct 2010 09:23:43 -0600 Subject: [PATCH v2 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287429922-18870-9-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-9-git-send-email-cyril@ti.com> Message-ID: <20101020152343.GB7285@angua.secretlab.ca> On Mon, Oct 18, 2010 at 03:25:18PM -0400, Cyril Chemparathy wrote: > This patch adds a GPIO driver based on TI's SSP device. This driver does not > support GPIO-IRQs. > > Signed-off-by: Cyril Chemparathy Acked-by: Grant Likely > --- > arch/arm/mach-davinci/include/mach/ti_ssp.h | 4 + > drivers/gpio/Kconfig | 10 ++ > drivers/gpio/Makefile | 1 + > drivers/gpio/ti-ssp-gpio.c | 200 +++++++++++++++++++++++++++ > 4 files changed, 215 insertions(+), 0 deletions(-) > create mode 100644 drivers/gpio/ti-ssp-gpio.c > > diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h > index 63c88fe..21f1429 100644 > --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h > +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h > @@ -39,6 +39,10 @@ struct ti_ssp_spi_data { > void (*select)(int cs); > }; > > +struct ti_ssp_gpio_data { > + int start; > +}; > + > /* > * Sequencer port IO pin configuration bits. These do not correlate 1-1 with > * the hardware. The iosel field in the port data combines iosel1 and iosel2, > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 510aa20..e400761 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -111,6 +111,16 @@ config GPIO_SCH > This driver can also be built as a module. If so, the module > will be called sch-gpio. > > +config GPIO_TI_SSP > + tristate "TI SSP Controller GPIO Driver" > + depends on GPIOLIB && TI_SSP > + help > + Say yes here to support a virtual GPIO interface on TI SSP ports. > + Each SSP port translates into 4 GPIOs, with no IRQ support. > + > + This driver can also be built as a module. If so, the module > + will be called ti-ssp-gpio. > + > comment "I2C GPIO expanders:" > > config GPIO_MAX7300 > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index fc6019d..98b4551 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o > obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o > obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o > obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o > +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o > obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o > obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o > obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o > diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c > new file mode 100644 > index 0000000..c046713 > --- /dev/null > +++ b/drivers/gpio/ti-ssp-gpio.c > @@ -0,0 +1,200 @@ > +/* > + * Sequencer Serial Port (SSP) based virtual GPIO driver > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +struct ti_ssp_gpio { > + struct gpio_chip chip; > +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) > + struct device *dev; > + spinlock_t lock; > + u8 out; > + u32 iosel; > +}; > + > +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int error = 0; > + > + spin_lock(&gpio->lock); > + > + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); > + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); > + > + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); > + > + spin_unlock(&gpio->lock); > + > + return error; > +} > + > +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int error; > + > + spin_lock(&gpio->lock); > + > + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); > + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); > + > + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); > + > + if (error < 0) > + goto error; > + > + if (val) > + gpio->out |= BIT(gpio_num); > + else > + gpio->out &= ~BIT(gpio_num); > + > + error = ti_ssp_raw_write(gpio->dev, gpio->out); > + > +error: > + spin_unlock(&gpio->lock); > + return error; > +} > + > +static int value_get(struct gpio_chip *chip, unsigned gpio_num) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int ret; > + > + spin_lock(&gpio->lock); > + > + ret = ti_ssp_raw_read(gpio->dev); > + if (ret >= 0) > + ret = (ret & BIT(gpio_num)) ? 1 : 0; > + > + spin_unlock(&gpio->lock); > + return ret; > +} > + > +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + > + spin_lock(&gpio->lock); > + > + if (val) > + gpio->out |= BIT(gpio_num); > + else > + gpio->out &= ~BIT(gpio_num); > + > + ti_ssp_raw_write(gpio->dev, gpio->out); > + > + spin_unlock(&gpio->lock); > +} > + > +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) > +{ > + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; > + struct device *dev = &pdev->dev; > + struct ti_ssp_gpio *gpio; > + int error; > + > + if (!pdata) { > + dev_err(dev, "platform data not found\n"); > + return -EINVAL; > + } > + > + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); > + if (!gpio) { > + dev_err(dev, "cannot allocate driver data\n"); > + return -ENOMEM; > + } > + > + gpio->dev = dev; > + gpio->iosel = SSP_PIN_SEL(0, SSP_IN) | SSP_PIN_SEL(1, SSP_IN) | > + SSP_PIN_SEL(2, SSP_IN) | SSP_PIN_SEL(3, SSP_IN); > + spin_lock_init(&gpio->lock); > + platform_set_drvdata(pdev, gpio); > + > + gpio->chip.base = pdata->start; > + gpio->chip.ngpio = 4; > + gpio->chip.dev = &pdev->dev; > + gpio->chip.label = "ti_ssp_gpio"; > + gpio->chip.owner = THIS_MODULE; > + gpio->chip.get = value_get; > + gpio->chip.set = value_set; > + gpio->chip.direction_input = direction_in; > + gpio->chip.direction_output = direction_out; > + > + error = gpiochip_add(&gpio->chip); > + if (error < 0) { > + dev_err(dev, "gpio chip registration failed (%d)\n", error); > + goto error; > + } > + > + dev_info(dev, "ssp gpio interface registered\n"); > + return 0; > + > +error: > + kfree(gpio); > + return error; > +} > + > +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) > +{ > + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); > + int error; > + > + error = gpiochip_remove(&gpio->chip); > + if (error < 0) > + return error; > + kfree(gpio); > + return 0; > +} > + > +static struct platform_driver ti_ssp_gpio_driver = { > + .probe = ti_ssp_gpio_probe, > + .remove = __devexit_p(ti_ssp_gpio_remove), > + .driver = { > + .name = "ti-ssp-gpio", > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init ti_ssp_gpio_init(void) > +{ > + return platform_driver_register(&ti_ssp_gpio_driver); > +} > +subsys_initcall(ti_ssp_gpio_init); > + > +static void __exit ti_ssp_gpio_exit(void) > +{ > + platform_driver_unregister(&ti_ssp_gpio_driver); > +} > +module_exit(ti_ssp_gpio_exit); > + > +MODULE_DESCRIPTION("GPIO interface for TI-SSP"); > +MODULE_AUTHOR("Cyril Chemparathy "); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:ti-ssp-gpio"); > -- > 1.7.0.4 > From grant.likely at secretlab.ca Wed Oct 20 10:32:51 2010 From: grant.likely at secretlab.ca (Grant Likely) Date: Wed, 20 Oct 2010 09:32:51 -0600 Subject: [PATCH v2 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1287429922-18870-5-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-5-git-send-email-cyril@ti.com> Message-ID: <20101020153251.GC7285@angua.secretlab.ca> On Mon, Oct 18, 2010 at 03:25:14PM -0400, Cyril Chemparathy wrote: > This patch adds an SPI master implementation that operates on top of an > underlying TI-SSP port. > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/include/mach/ti_ssp.h | 5 + > drivers/spi/Kconfig | 7 + > drivers/spi/Makefile | 1 + > drivers/spi/spi_ti_ssp.c | 397 +++++++++++++++++++++++++++ > 4 files changed, 410 insertions(+), 0 deletions(-) > create mode 100644 drivers/spi/spi_ti_ssp.c Minor comments below, but otherwise: Acked-by: Grant Likely This patch should be merged with the rest of the series. I don't think there is any point in me picking it up into the SPI tree. > > diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h > index 51afc42..63c88fe 100644 > --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h > +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h > @@ -34,6 +34,11 @@ struct ti_ssp_data { > struct ti_ssp_dev_data dev_data[2]; > }; > > +struct ti_ssp_spi_data { > + int num_cs; > + void (*select)(int cs); > +}; Hmmm. I really should look into standardizing the way spi busses handle slave selects. In particular, it would be valuable to have a stock method for the common case of simple gpios used for ss lines. (Not a critique on this patch, just thinking out loud). > + > /* > * Sequencer port IO pin configuration bits. These do not correlate 1-1 with > * the hardware. The iosel field in the port data combines iosel1 and iosel2, > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig > index 91c2f4f..be86354 100644 > --- a/drivers/spi/Kconfig > +++ b/drivers/spi/Kconfig > @@ -298,6 +298,13 @@ config SPI_STMP3XXX > help > SPI driver for Freescale STMP37xx/378x SoC SSP interface > > +config SPI_TI_SSP > + tristate "TI SSP Controller SPI Driver" > + depends on SPI_MASTER && TI_SSP This is already in the "if SPI_MASTER" block. Make it simply "depends on TI_SSP". > + help > + This selects an SPI master implementation using a TI sequencer > + serial port. > + > config SPI_TXX9 > tristate "Toshiba TXx9 SPI controller" > depends on GENERIC_GPIO && CPU_TX49XX > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile > index e9cbd18..953aba7 100644 > --- a/drivers/spi/Makefile > +++ b/drivers/spi/Makefile > @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o > obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o > obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o > obj-$(CONFIG_SPI_TXX9) += spi_txx9.o > +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o Nit: Try to keep the list both a) in the same order as Kconfig, and b) in alphabetical order (I know the kernel list isn't very close to alphabetical, but try not to make it worse). :-) > obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o > obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o > obj-$(CONFIG_SPI_XILINX_PLTFM) += xilinx_spi_pltfm.o > diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c > new file mode 100644 > index 0000000..a566158 > --- /dev/null > +++ b/drivers/spi/spi_ti_ssp.c > @@ -0,0 +1,397 @@ > +/* > + * Sequencer Serial Port (SSP) based SPI master driver > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) > + > +struct ti_ssp_spi { > + const struct ti_ssp_spi_data *pdata; > + struct spi_master *master; > + struct device *dev; > + spinlock_t lock; > + struct list_head msg_queue; > + struct completion complete; > + int shutdown:1; > + struct workqueue_struct *workqueue; > + struct work_struct work; > + u8 mode, bpw; > + int cs_active; > + u32 pc_en, pc_dis, pc_wr, pc_rd; > +}; > + > +static u32 do_read_data(struct ti_ssp_spi *hw) > +{ > + u32 ret; > + > + ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); > + return ret; > +} > + > +static void do_write_data(struct ti_ssp_spi *hw, u32 data) > +{ > + ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); > +} > + > +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, > + struct spi_transfer *t) > +{ > + int count; > + > + if (hw->bpw <= 8) { > + u8 *rx = t->rx_buf; > + const u8 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 1) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } else if (hw->bpw <= 16) { > + u16 *rx = t->rx_buf; > + const u16 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 2) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } else { > + u32 *rx = t->rx_buf; > + const u32 *tx = t->tx_buf; > + > + for (count = 0; count < t->len; count += 4) { > + if (t->tx_buf) > + do_write_data(hw, *tx++); > + if (t->rx_buf) > + *rx++ = do_read_data(hw); > + } > + } > + > + msg->actual_length += count; /* bytes transferred */ > + > + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", > + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, > + hw->bpw, count, (count < t->len) ? " (under)" : ""); > + > + return (count < t->len) ? -EIO : 0; /* left over data */ > +} > + > +static void chip_select(struct ti_ssp_spi *hw, int cs_active) > +{ > + cs_active = !!cs_active; > + if (cs_active == hw->cs_active) > + return; > + ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); > + hw->cs_active = cs_active; > +} > + > +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ > + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) > +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ > + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) > + > +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) > +{ > + int error, idx = 0; > + u32 seqram[16]; > + u32 cs_en, cs_dis, clk; > + u32 topbits, botbits; > + > + mode &= MODE_BITS; > + if (mode == hw->mode && bpw == hw->bpw) > + return 0; > + > + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; > + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; > + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; > + > + /* Construct instructions */ > + > + /* Disable Chip Select */ > + hw->pc_dis = idx; > + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; > + > + /* Enable Chip Select */ > + hw->pc_en = idx; > + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + /* Reads and writes need to be split for bpw > 16 */ > + topbits = (bpw > 16) ? 16 : bpw; > + botbits = bpw - topbits; > + > + /* Write */ > + hw->pc_wr = idx; > + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; > + if (botbits) > + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + /* Read */ > + hw->pc_rd = idx; > + if (botbits) > + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; > + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; > + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; > + > + error = ti_ssp_load(hw->dev, 0, seqram, idx); > + if (error < 0) > + return error; > + > + error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? > + 0 : SSP_EARLY_DIN)); > + if (error < 0) > + return error; > + > + hw->bpw = bpw; > + hw->mode = mode; > + > + return error; > +} > + > +static void ti_ssp_spi_work(struct work_struct *work) > +{ > + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); > + > + spin_lock_irq(&hw->lock); > + > + while (!list_empty(&hw->msg_queue)) { > + struct spi_message *m; > + struct spi_device *spi; > + struct spi_transfer *t = NULL; > + int status = 0; > + > + m = container_of(hw->msg_queue.next, struct spi_message, > + queue); > + > + list_del_init(&m->queue); > + > + spi = m->spi; > + > + if (hw->pdata->select) > + hw->pdata->select(spi->chip_select); > + > + list_for_each_entry(t, &m->transfers, transfer_list) { > + int bpw = spi->bits_per_word; > + int xfer_status; > + > + if (t->bits_per_word) > + bpw = t->bits_per_word; > + > + if (setup_xfer(hw, bpw, spi->mode) < 0) > + break; > + > + chip_select(hw, 1); > + > + spin_unlock_irq(&hw->lock); > + > + xfer_status = do_transfer(hw, m, t); > + if (xfer_status < 0) > + status = xfer_status; > + > + if (t->delay_usecs) > + udelay(t->delay_usecs); > + > + spin_lock_irq(&hw->lock); > + > + if (t->cs_change) > + chip_select(hw, 0); > + } > + > + chip_select(hw, 0); > + m->status = status; > + m->complete(m->context); > + } > + > + if (hw->shutdown) > + complete(&hw->complete); > + > + spin_unlock_irq(&hw->lock); > +} > + > +static int ti_ssp_spi_setup(struct spi_device *spi) > +{ > + if (spi->bits_per_word > 32) > + return -EINVAL; > + > + return 0; > +} > + > +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) > +{ > + struct ti_ssp_spi *hw; > + struct spi_transfer *t; > + unsigned long flags; > + int error = 0; > + > + m->actual_length = 0; > + m->status = -EINPROGRESS; > + > + hw = spi_master_get_devdata(spi->master); > + > + if (list_empty(&m->transfers) || !m->complete) > + return -EINVAL; > + > + list_for_each_entry(t, &m->transfers, transfer_list) { > + if (t->len && !(t->rx_buf || t->tx_buf)) { > + dev_err(&spi->dev, "invalid xfer, no buffer\n"); > + return -EINVAL; > + } > + > + if (t->len && t->rx_buf && t->tx_buf) { > + dev_err(&spi->dev, "invalid xfer, full duplex\n"); > + return -EINVAL; > + } > + > + if (t->bits_per_word > 32) { > + dev_err(&spi->dev, "invalid xfer width %d\n", > + t->bits_per_word); > + return -EINVAL; > + } > + } > + > + spin_lock_irqsave(&hw->lock, flags); > + if (hw->shutdown) { > + error = -ESHUTDOWN; > + goto error_unlock; > + } > + list_add_tail(&m->queue, &hw->msg_queue); > + queue_work(hw->workqueue, &hw->work); > +error_unlock: > + spin_unlock_irqrestore(&hw->lock, flags); > + return error; > +} > + > +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) > +{ > + const struct ti_ssp_spi_data *pdata; > + struct ti_ssp_spi *hw; > + struct spi_master *master; > + struct device *dev = &pdev->dev; > + int error = 0; > + > + pdata = dev->platform_data; > + if (!pdata) { > + dev_err(dev, "platform data not found\n"); > + return -EINVAL; > + } > + > + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); > + if (!master) { > + dev_err(dev, "cannot allocate SPI master\n"); > + return -ENOMEM; > + } > + > + hw = spi_master_get_devdata(master); > + platform_set_drvdata(pdev, hw); > + > + hw->master = master; > + hw->dev = dev; > + hw->pdata = pdata; > + > + spin_lock_init(&hw->lock); > + init_completion(&hw->complete); > + INIT_LIST_HEAD(&hw->msg_queue); > + INIT_WORK(&hw->work, ti_ssp_spi_work); > + > + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); > + if (!hw->workqueue) { > + error = -ENOMEM; > + dev_err(dev, "work queue creation failed\n"); > + goto error_wq; > + } > + > + master->bus_num = pdev->id; > + master->num_chipselect = hw->pdata->num_cs; > + master->mode_bits = MODE_BITS; > + master->flags = SPI_MASTER_HALF_DUPLEX; > + master->setup = ti_ssp_spi_setup; > + master->transfer = ti_ssp_spi_transfer; > + > + error = spi_register_master(master); > + if (error) { > + dev_err(dev, "master registration failed\n"); > + goto error_reg; > + } > + > + return 0; > + > +error_reg: > + destroy_workqueue(hw->workqueue); > +error_wq: > + spi_master_put(master); > + return error; > +} > + > +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) > +{ > + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); > + int error; > + > + hw->shutdown = 1; > + while (!list_empty(&hw->msg_queue)) { > + error = wait_for_completion_interruptible(&hw->complete); > + if (error < 0) { > + hw->shutdown = 0; > + return error; > + } > + } > + destroy_workqueue(hw->workqueue); > + spi_unregister_master(hw->master); > + > + return 0; > +} > + > +static struct platform_driver ti_ssp_spi_driver = { > + .probe = ti_ssp_spi_probe, > + .remove = __devexit_p(ti_ssp_spi_remove), > + .driver = { > + .name = "ti-ssp-spi", > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init ti_ssp_spi_init(void) > +{ > + return platform_driver_register(&ti_ssp_spi_driver); > +} > +subsys_initcall(ti_ssp_spi_init); > + > +static void __exit ti_ssp_spi_exit(void) > +{ > + platform_driver_unregister(&ti_ssp_spi_driver); > +} > +module_exit(ti_ssp_spi_exit); > + > +MODULE_DESCRIPTION("SSP SPI Master"); > +MODULE_AUTHOR("Cyril Chemparathy"); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:spi_ti_ssp"); > -- > 1.7.0.4 > From renegs.2378 at gmail.com Wed Oct 20 11:57:10 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 11:57:10 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds EMAC support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 47 > +++++++++++++++++++++++++++ > 1 files changed, 47 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..8633245 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,51 @@ > > #include > #include > +#include > + > +#define HAWKBOARD_PHY_ID "0:07" > + > +static short omapl138_hawk_mii_pins[] __initdata = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 > +}; > + > +static __init void omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info = &davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return; > + > + val = __raw_readl(cfgchip3); > + > + val &= ~BIT(8); > + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); > + if (ret) { > + pr_warning("%s: cpgmac/mii mux setup failed: %d\n", > + __func__, ret); > + return; > + } > + > + /* configure the CFGCHIP3 register for MII */ > + __raw_writel(val, cfgchip3); > + pr_info("EMAC: MII PHY configured\n"); > + > + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; > + > + ret = da8xx_register_emac(); > + if (ret) > + pr_warning("%s: emac registration failed: %d\n", > + __func__, ret); > +} > + > > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > @@ -30,6 +75,8 @@ static __init void omapl138_hawk_init(void) > > davinci_serial_init(&omapl138_hawk_uart_config); > > + omapl138_hawk_config_emac(); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:00:20 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:00:20 -0500 Subject: [PATCH v5 2/9] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-3-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-3-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds EDMA support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 54 > +++++++++++++++++++++++++++ > 1 files changed, 54 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 8633245..ef3974e 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -64,6 +64,55 @@ static __init void omapl138_hawk_config_emac(void) > __func__, ret); > } > > +/* > + * The following EDMA channels/slots are not being used by drivers (for > + * example: Timer, GPIO, UART events etc) on da850/omap-l138 > EVM/Hawkboard, > + * hence they are being reserved for codecs on the DSP side. > + */ > +static const s16 da850_dma0_rsv_chans[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma0_rsv_slots[][2] = { > + /* (offset, number) */ > + { 8, 6}, > + {24, 4}, > + {30, 50}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_chans[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 2}, > + {-1, -1} > +}; > + > +static const s16 da850_dma1_rsv_slots[][2] = { > + /* (offset, number) */ > + { 0, 28}, > + {30, 90}, > + {-1, -1} > +}; > + > +static struct edma_rsv_info da850_edma_cc0_rsv = { > + .rsv_chans = da850_dma0_rsv_chans, > + .rsv_slots = da850_dma0_rsv_slots, > +}; > + > +static struct edma_rsv_info da850_edma_cc1_rsv = { > + .rsv_chans = da850_dma1_rsv_chans, > + .rsv_slots = da850_dma1_rsv_slots, > +}; > + > +static struct edma_rsv_info *da850_edma_rsv[2] = { > + &da850_edma_cc0_rsv, > + &da850_edma_cc1_rsv, > +}; > > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > @@ -77,6 +126,11 @@ static __init void omapl138_hawk_init(void) > > omapl138_hawk_config_emac(); > > + ret = da850_register_edma(da850_edma_rsv); > + if (ret) > + pr_warning("%s: EDMA registration failed: %d\n", > + __func__, ret); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:11:49 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:11:49 -0500 Subject: [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds ASoC support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > sound/soc/davinci/Kconfig | 5 +++-- > sound/soc/davinci/davinci-evm.c | 6 ++++-- > 2 files changed, 7 insertions(+), 4 deletions(-) > > diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig > index 6bbf001..72c6752 100644 > --- a/sound/soc/davinci/Kconfig > +++ b/sound/soc/davinci/Kconfig > @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM > DA830/OMAP-L137 EVM > > config SND_DA850_SOC_EVM > - tristate "SoC Audio support for DA850/OMAP-L138 EVM" > - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM > + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" > + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ > + MACH_OMAPL138_HAWKBOARD) > select SND_DAVINCI_SOC_MCASP > select SND_SOC_TLV320AIC3X > help > diff --git a/sound/soc/davinci/davinci-evm.c > b/sound/soc/davinci/davinci-evm.c > index 97f74d6..73093eb 100644 > --- a/sound/soc/davinci/davinci-evm.c > +++ b/sound/soc/davinci/davinci-evm.c > @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream > *substream, > sysclk = 12288000; > > else if (machine_is_davinci_da830_evm() || > - machine_is_davinci_da850_evm()) > + machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) > sysclk = 24576000; > > else > @@ -311,7 +312,8 @@ static int __init evm_init(void) > } else if (machine_is_davinci_da830_evm()) { > evm_snd_dev_data = &da830_evm_snd_devdata; > index = 1; > - } else if (machine_is_davinci_da850_evm()) { > + } else if (machine_is_davinci_da850_evm() || > + machine_is_omapl138_hawkboard()) { > evm_snd_dev_data = &da850_evm_snd_devdata; > index = 0; > } else > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:12:36 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:12:36 -0500 Subject: [PATCH v5 4/9] davinci: McASP configuration for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-5-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-5-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch defines Pin Mux configuration for MacASP > used on the Hawkboard-L138 system in order to add Audio support > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > arch/arm/mach-davinci/da850.c | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 63916b9..f033a0a 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { > const short da850_mcasp_pins[] __initdata = { > DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, > DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, > - DA850_AXR_11, DA850_AXR_12, > + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, > -1 > }; > > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:13:22 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:13:22 -0500 Subject: [PATCH v5 5/9] davinci: Audio support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-6-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-6-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds sound support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > Notes: > > This patch works with da8xx_omapl_defconfig > > In order to test ALSA utils select in menuconfig like insmodule: > > Sound card support ---> > Advanced Linux Sound Architecture ---> > ALSA for SoC audio support ---> > SoC Audio for the TI DAVINCI chip > SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard > > arch/arm/mach-davinci/board-omapl138-hawk.c | 46 > +++++++++++++++++++++++++++ > 1 files changed, 46 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index ef3974e..97836e9 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -13,6 +13,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -114,6 +115,38 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { > &da850_edma_cc1_rsv, > }; > > +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { > + { > + I2C_BOARD_INFO("tlv320aic3x", 0x18), > + }, > +}; > + > +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { > + .bus_freq = 100, /* kHz */ > + .bus_delay = 0, /* usec */ > +}; > + > +/* davinci Hawkboard audio machine driver */ > +static u8 da850_iis_serializer_direction[] = { > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, > + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, > +}; > + > +static struct snd_platform_data omapl138_hawk_snd_data = { > + .tx_dma_offset = 0x2000, > + .rx_dma_offset = 0x2000, > + .op_mode = DAVINCI_MCASP_IIS_MODE, > + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), > + .tdm_slots = 2, > + .serial_dir = da850_iis_serializer_direction, > + .asp_chan_q = EVENTQ_1, > + .version = MCASP_VERSION_2, > + .txnumevt = 1, > + .rxnumevt = 1, > +}; > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; > @@ -131,6 +164,19 @@ static __init void omapl138_hawk_init(void) > pr_warning("%s: EDMA registration failed: %d\n", > __func__, ret); > > + i2c_register_board_info(1, omapl138_hawk_i2c_devices, > + ARRAY_SIZE(omapl138_hawk_i2c_devices)); > + > + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); > + if (ret) > + pr_warning("%s: i2c0 registration failed: %d\n", > + __func__, ret); > + > + ret = davinci_cfg_reg_list(da850_mcasp_pins); > + if (ret) > + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, > ret); > + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:14:05 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:14:05 -0500 Subject: [PATCH v5 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-7-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-7-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch defines Pin Mux configuration to enable MMC/SD > and USB-OHCI on the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > arch/arm/mach-davinci/da850.c | 4 ++++ > arch/arm/mach-davinci/include/mach/mux.h | 4 ++++ > 2 files changed, 8 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index f033a0a..4458bff 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -543,11 +543,15 @@ static const struct mux_config da850_pins[] = { > MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, > false) > MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, > false) > /* GPIO function */ > + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, > false) > MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, > false) > MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, > false) > MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, > false) > + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, > false) > + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, > false) > MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, > false) > MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, > false) > + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, > false) > MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, > false) > #endif > }; > diff --git a/arch/arm/mach-davinci/include/mach/mux.h > b/arch/arm/mach-davinci/include/mach/mux.h > index de11aac..5d4e0fe 100644 > --- a/arch/arm/mach-davinci/include/mach/mux.h > +++ b/arch/arm/mach-davinci/include/mach/mux.h > @@ -908,11 +908,15 @@ enum davinci_da850_index { > DA850_NEMA_CS_2, > > /* GPIO function */ > + DA850_GPIO2_4, > DA850_GPIO2_6, > DA850_GPIO2_8, > DA850_GPIO2_15, > + DA850_GPIO3_12, > + DA850_GPIO3_13, > DA850_GPIO4_0, > DA850_GPIO4_1, > + DA850_GPIO6_13, > DA850_RTC_ALARM, > }; > > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:15:04 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:15:04 -0500 Subject: [PATCH v5 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <1287511587-22216-8-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-8-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds MMC/SD support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > Notes: > > This patch works with da8xx_omapl_defconfig > In order to test it select in menuconfig like insmodule > > MMC/SD/SDIO card support ---> > MMC block device driver > Use bounce buffer for simple hosts > TI DAVINCI Multimedia Card Interface support > > arch/arm/mach-davinci/board-omapl138-hawk.c | 63 > +++++++++++++++++++++++++++ > 1 files changed, 63 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index 97836e9..c83050b 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -23,6 +23,8 @@ > #include > > #define HAWKBOARD_PHY_ID "0:07" > +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) > +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) > > static short omapl138_hawk_mii_pins[] __initdata = { > DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > @@ -147,6 +149,65 @@ static struct snd_platform_data omapl138_hawk_snd_data > = { > .rxnumevt = 1, > }; > > +static const short hawk_mmcsd0_pins[] = { > + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, > + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, > + DA850_GPIO3_12, DA850_GPIO3_13, > + -1 > +}; > + > +static int da850_hawk_mmc_get_ro(int index) > +{ > + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); > +} > + > +static int da850_hawk_mmc_get_cd(int index) > +{ > + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); > +} > + > +static struct davinci_mmc_config da850_mmc_config = { > + .get_ro = da850_hawk_mmc_get_ro, > + .get_cd = da850_hawk_mmc_get_cd, > + .wires = 4, > + .max_freq = 50000000, > + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, > + .version = MMC_CTLR_VERSION_2, > +}; > + > +static __init void omapl138_hawk_mmc_init(void) > +{ > + int ret; > + > + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); > + if (ret) { > + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", > + __func__, ret); > + return; > + } > + > + ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, > + GPIOF_DIR_IN, "MMC CD"); > + if (ret < 0) { > + pr_warning("%s: can not open GPIO %d\n", > + __func__, DA850_HAWK_MMCSD_CD_PIN); > + return; > + } > + > + ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN, > + GPIOF_DIR_IN, "MMC WP"); > + if (ret < 0) { > + pr_warning("%s: can not open GPIO %d\n", > + __func__, DA850_HAWK_MMCSD_WP_PIN); > + return; > + } > + > + ret = da8xx_register_mmcsd0(&da850_mmc_config); > + if (ret) > + pr_warning("%s: MMC/SD0 registration failed: %d\n", > + __func__, ret); > +} > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; > @@ -177,6 +238,8 @@ static __init void omapl138_hawk_init(void) > pr_warning("%s: mcasp mux setup failed: %d\n", __func__, > ret); > da8xx_register_mcasp(0, &omapl138_hawk_snd_data); > > + omapl138_hawk_mmc_init(); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:16:05 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:16:05 -0500 Subject: [PATCH v5 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-9-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-9-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > arch/arm/mach-davinci/da850.c | 16 ++++++++++++++++ > 1 files changed, 16 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c > index 4458bff..b3b1adb 100644 > --- a/arch/arm/mach-davinci/da850.c > +++ b/arch/arm/mach-davinci/da850.c > @@ -345,6 +345,20 @@ static struct clk aemif_clk = { > .flags = ALWAYS_ENABLED, > }; > > +static struct clk usb11_clk = { > + .name = "usb11", > + .parent = &pll0_sysclk4, > + .lpsc = DA8XX_LPSC1_USB11, > + .gpsc = 1, > +}; > + > +static struct clk usb20_clk = { > + .name = "usb20", > + .parent = &pll0_sysclk2, > + .lpsc = DA8XX_LPSC1_USB20, > + .gpsc = 1, > +}; > + > static struct clk_lookup da850_clks[] = { > CLK(NULL, "ref", &ref_clk), > CLK(NULL, "pll0", &pll0_clk), > @@ -387,6 +401,8 @@ static struct clk_lookup da850_clks[] = { > CLK("davinci_mmc.0", NULL, &mmcsd0_clk), > CLK("davinci_mmc.1", NULL, &mmcsd1_clk), > CLK(NULL, "aemif", &aemif_clk), > + CLK(NULL, "usb11", &usb11_clk), > + CLK(NULL, "usb20", &usb20_clk), > CLK(NULL, NULL, NULL), > }; > > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From renegs.2378 at gmail.com Wed Oct 20 12:16:57 2010 From: renegs.2378 at gmail.com (Rene Gonzalez) Date: Wed, 20 Oct 2010 12:16:57 -0500 Subject: [PATCH v5 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-10-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-10-git-send-email-vm.rod25@gmail.com> Message-ID: On Tue, Oct 19, 2010 at 1:06 PM, wrote: > From: Victor Rodriguez > > This patch adds USB1.1 support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > Tested-by: Rene Gonzalez > --- > Notes: > > This patch works with da8xx_omapl_defconfig > In order to test it select in menuconfig like insmodule > > Device Drivers ---> > SCSI device support ---> > SCSI device support > legacy /proc/scsi/ support > SCSI disk support > SCSI low-level drivers > > USB support ---> > Support for Host-side US > OHCI HCD support (NEW) > USB Mass Storage support (NEW) > USB Gadget Support ---> > USB Gadget Drivers (Ethernet Gadget\ > (with CDC Ethernet support)) ---> > NOP USB Transceiver Driver > > And you will be able to mount and USB pen drive > > In order to connect a keyboard or a mouse on a USB-hub > select in menuconfig like insmodule > > HID Devices ---> > Generic HID support > USB Human Interface Device (full HID) support > > arch/arm/mach-davinci/board-omapl138-hawk.c | 107 > +++++++++++++++++++++++++++ > 1 files changed, 107 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c > b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c83050b..1531717 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -26,6 +26,9 @@ > #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) > #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) > > +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) > +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) > + > static short omapl138_hawk_mii_pins[] __initdata = { > DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > @@ -208,6 +211,108 @@ static __init void omapl138_hawk_mmc_init(void) > __func__, ret); > } > > +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); > +static da8xx_ocic_handler_t hawk_usb_ocic_handler; > + > +static const short da850_hawk_usb11_pins[] = { > + DA850_GPIO2_4, DA850_GPIO6_13, > + -1 > +}; > + > +static int hawk_usb_set_power(unsigned port, int on) > +{ > + gpio_set_value(DA850_USB1_VBUS_PIN, on); > + return 0; > +} > + > +static int hawk_usb_get_power(unsigned port) > +{ > + return gpio_get_value(DA850_USB1_VBUS_PIN); > +} > + > +static int hawk_usb_get_oci(unsigned port) > +{ > + return !gpio_get_value(DA850_USB1_OC_PIN); > +} > + > +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) > +{ > + int irq = gpio_to_irq(DA850_USB1_OC_PIN); > + int error = 0; > + > + if (handler != NULL) { > + hawk_usb_ocic_handler = handler; > + > + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, > + IRQF_DISABLED | IRQF_TRIGGER_RISING > | > + IRQF_TRIGGER_FALLING, > + "OHCI over-current indicator", > NULL); > + if (error) > + pr_err(KERN_ERR "%s: could not request IRQ to watch > " > + "over-current indicator changes\n", > __func__); > + } else > + free_irq(irq, NULL); > + > + return error; > +} > + > +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { > + .set_power = hawk_usb_set_power, > + .get_power = hawk_usb_get_power, > + .get_oci = hawk_usb_get_oci, > + .ocic_notify = hawk_usb_ocic_notify, > + /* TPS2087 switch @ 5V */ > + .potpgt = (3 + 1) / 2, /* 3 ms max */ > +}; > + > +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) > +{ > + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); > + return IRQ_HANDLED; > +} > + > +static __init void omapl138_hawk_usb_init(void) > +{ > + int ret; > + u32 cfgchip2; > + > + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); > + if (ret) { > + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", > + __func__, ret); > + return; > + } > + > + /* > + * Setup the Ref. clock frequency for the HAWK at 24 MHz. > + */ > + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + cfgchip2 &= ~CFGCHIP2_REFFREQ; > + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; > + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); > + > + ret = gpio_request_one(DA850_USB1_VBUS_PIN, > + GPIOF_DIR_OUT, "USB1 VBUS"); > + if (ret < 0) { > + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 > port " > + "power control: %d\n", __func__, ret); > + return; > + } > + > + ret = gpio_request_one(DA850_USB1_OC_PIN, > + GPIOF_DIR_IN, "USB1 OC"); > + if (ret < 0) { > + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 > port " > + "over-current indicator: %d\n", __func__, ret); > + return; > + } > + > + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); > + if (ret) > + pr_warning("%s: USB 1.1 registration failed: %d\n", > + __func__, ret); > +} > + > static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { > .enabled_uarts = 0x7, > }; > @@ -240,6 +345,8 @@ static __init void omapl138_hawk_init(void) > > omapl138_hawk_mmc_init(); > > + omapl138_hawk_usb_init(); > + > ret = da8xx_register_watchdog(); > if (ret) > pr_warning("omapl138_hawk_init: " > -- > 1.6.0.5 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cyril at ti.com Wed Oct 20 16:49:56 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Wed, 20 Oct 2010 17:49:56 -0400 Subject: [PATCH 1/2] davinci: use divide ratio limits from pll_data In-Reply-To: <1287611397-14974-1-git-send-email-cyril@ti.com> References: <1287611397-14974-1-git-send-email-cyril@ti.com> Message-ID: <1287611397-14974-2-git-send-email-cyril@ti.com> This patch modifies the sysclk rate setting code to use the divider mask specified in pll_data. Without this, devices with different divider ranges (e.g. tnetv107x) fail. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/clock.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 01ba080..e4e3af1 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -336,7 +336,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) ratio--; } - if (ratio > PLLDIV_RATIO_MASK) + if (ratio > pll->div_ratio_mask) return -EINVAL; do { @@ -344,7 +344,7 @@ int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate) } while (v & PLLSTAT_GOSTAT); v = __raw_readl(pll->base + clk->div_reg); - v &= ~PLLDIV_RATIO_MASK; + v &= ~pll->div_ratio_mask; v |= ratio | PLLDIV_EN; __raw_writel(v, pll->base + clk->div_reg); -- 1.7.0.4 From cyril at ti.com Wed Oct 20 16:49:55 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Wed, 20 Oct 2010 17:49:55 -0400 Subject: [PATCH 0/2] davinci: clock control fixes Message-ID: <1287611397-14974-1-git-send-email-cyril@ti.com> This series applies a few fixes necessary to get tnetv107x hardware functioning properly. A summary of these fixes follow: - davinci: fix sysclk rate setting code to allow for larger divider values - tnetv107x: reparent tnetv107x usb clocks to usbss - tnetv107x: mark timer1 as always enabled - tnetv107x: enable set_rate on pll divider output clocks - tnetv107x: fix invalid reset defaults on tsc sysclk divider Cyril Chemparathy (2): davinci: use divide ratio limits from pll_data davinci: minor tnetv107x clock tree fixes arch/arm/mach-davinci/clock.c | 4 ++-- arch/arm/mach-davinci/devices-tnetv107x.c | 15 ++++++++++++++- arch/arm/mach-davinci/tnetv107x.c | 23 ++++++++++++----------- 3 files changed, 28 insertions(+), 14 deletions(-) From cyril at ti.com Wed Oct 20 16:49:57 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Wed, 20 Oct 2010 17:49:57 -0400 Subject: [PATCH 2/2] davinci: minor tnetv107x clock tree fixes In-Reply-To: <1287611397-14974-1-git-send-email-cyril@ti.com> References: <1287611397-14974-1-git-send-email-cyril@ti.com> Message-ID: <1287611397-14974-3-git-send-email-cyril@ti.com> This patch applies the following modifications to the tnetv107x clock tree: - reparent tnetv107x usb clocks to usbss - mark timer1 as always enabled - enable set_rate on pll divider output clocks - adjust tnetv107x tsc sysclk rate lower to fix invalid reset defaults Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 15 ++++++++++++++- arch/arm/mach-davinci/tnetv107x.c | 23 ++++++++++++----------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index c9a86d8..85503de 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -344,7 +344,20 @@ static struct platform_device tsc_device = { void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { - int i; + int i, error; + struct clk *tsc_clk; + + /* + * The reset defaults for tnetv107x tsc clock divider is set too high. + * This forces the clock down to a range that allows the ADC to + * complete sample conversion in time. + */ + tsc_clk = clk_get(NULL, "sys_tsc_clk"); + if (tsc_clk) { + error = clk_set_rate(tsc_clk, 5000000); + WARN_ON(error < 0); + clk_put(tsc_clk); + } platform_device_register(&edma_device); platform_device_register(&tnetv107x_wdt_device); diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index daeae06..6fcdece 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -131,12 +131,13 @@ define_pll_clk(tdm, 1, 0x0ff, 0x200); define_pll_clk(eth, 2, 0x0ff, 0x400); /* Level 2 - divided outputs from the PLLs */ -#define define_pll_div_clk(pll, cname, div) \ - static struct clk pll##_##cname##_clk = { \ - .name = #pll "_" #cname "_clk",\ - .parent = &pll_##pll##_clk, \ - .flags = CLK_PLL, \ - .div_reg = PLLDIV##div, \ +#define define_pll_div_clk(pll, cname, div) \ + static struct clk pll##_##cname##_clk = { \ + .name = #pll "_" #cname "_clk", \ + .parent = &pll_##pll##_clk, \ + .flags = CLK_PLL, \ + .div_reg = PLLDIV##div, \ + .set_rate = davinci_set_sysclk_rate, \ } define_pll_div_clk(sys, arm1176, 1); @@ -192,6 +193,7 @@ lpsc_clk_enabled(system, sys_half_clk, SYSTEM); lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST); lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST); lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM); +lpsc_clk_enabled(timer1, sys_half_clk, TIMER1); lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE); lpsc_clk(ethss, eth_125mhz_clk, ETHSS); @@ -205,16 +207,15 @@ lpsc_clk(mdio, sys_half_clk, MDIO); lpsc_clk(sdio0, sys_half_clk, SDIO0); lpsc_clk(sdio1, sys_half_clk, SDIO1); lpsc_clk(timer0, sys_half_clk, TIMER0); -lpsc_clk(timer1, sys_half_clk, TIMER1); lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP); lpsc_clk(ssp, sys_half_clk, SSP); lpsc_clk(tdm0, tdm_0_clk, TDM0); lpsc_clk(tdm1, tdm_1_clk, TDM1); lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ); lpsc_clk(mcdma, sys_half_clk, MCDMA); -lpsc_clk(usb0, sys_half_clk, USB0); -lpsc_clk(usb1, sys_half_clk, USB1); lpsc_clk(usbss, sys_half_clk, USBSS); +lpsc_clk(usb0, clk_usbss, USB0); +lpsc_clk(usb1, clk_usbss, USB1); lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII); lpsc_clk(imcop, sys_dsp_clk, IMCOP); lpsc_clk(spare, sys_half_clk, SPARE); @@ -281,7 +282,9 @@ static struct clk_lookup clks[] = { CLK(NULL, "clk_tdm0", &clk_tdm0), CLK(NULL, "clk_vlynq", &clk_vlynq), CLK(NULL, "clk_mcdma", &clk_mcdma), + CLK(NULL, "clk_usbss", &clk_usbss), CLK(NULL, "clk_usb0", &clk_usb0), + CLK(NULL, "clk_usb1", &clk_usb1), CLK(NULL, "clk_tdm1", &clk_tdm1), CLK(NULL, "clk_debugss", &clk_debugss), CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii), @@ -289,8 +292,6 @@ static struct clk_lookup clks[] = { CLK(NULL, "clk_imcop", &clk_imcop), CLK(NULL, "clk_spare", &clk_spare), CLK("davinci_mmc.1", NULL, &clk_sdio1), - CLK(NULL, "clk_usb1", &clk_usb1), - CLK(NULL, "clk_usbss", &clk_usbss), CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst), CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst), CLK(NULL, NULL, NULL), -- 1.7.0.4 From 274040551 at qq.com Thu Oct 14 23:28:18 2010 From: 274040551 at qq.com (yj2133011) Date: Thu, 14 Oct 2010 21:28:18 -0700 (PDT) Subject: [PATCH v3 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> References: <1287076899-4365-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287116898440-5637667.post@n2.nabble.com> Write good cheer, host. -------------------------------------------------------- If you're looking for a http://www.tomtop.com/24w-2000lm-ultra-bright-hid-xenon-flashlight-torch-icr18650-ipx3-waterproof.html?aid=z Xenon Flashlight , you should be aware that there are actually two different types of flashlights that fall under that label.just now i got http://www.tomtop.com/100-original-ps3-break-modchip-for-sony-ps3-game.html?aid=z PS3 Break Dongle . -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/PATCH-v3-1-9-davinci-EMAC-support-for-Omapl138-Hawkboard-tp5635872p5637667.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. From 274040551 at qq.com Thu Oct 14 23:28:27 2010 From: 274040551 at qq.com (yj2133011) Date: Thu, 14 Oct 2010 21:28:27 -0700 (PDT) Subject: [PATCH v4 0/9] Add Omapl138-Hawkboard support In-Reply-To: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> References: <1287112105-11968-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287116907284-5637668.post@n2.nabble.com> Write good cheer, host. -------------------------------------------------------- If you're looking for a http://www.tomtop.com/24w-2000lm-ultra-bright-hid-xenon-flashlight-torch-icr18650-ipx3-waterproof.html?aid=z Xenon Flashlight , you should be aware that there are actually two different types of flashlights that fall under that label.just now i got http://www.tomtop.com/100-original-ps3-break-modchip-for-sony-ps3-game.html?aid=z PS3 Break Dongle . -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/PATCH-v4-0-9-Add-Omapl138-Hawkboard-support-tp5637534p5637668.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. From 274040551 at qq.com Thu Oct 14 23:28:34 2010 From: 274040551 at qq.com (yj2133011) Date: Thu, 14 Oct 2010 21:28:34 -0700 (PDT) Subject: Problem with UART1 on Davinci with OMAP-L138 ? In-Reply-To: References: Message-ID: <1287116914846-5637669.post@n2.nabble.com> Write good cheer, host. -------------------------------------------------------- If you're looking for a http://www.tomtop.com/24w-2000lm-ultra-bright-hid-xenon-flashlight-torch-icr18650-ipx3-waterproof.html?aid=z Xenon Flashlight , you should be aware that there are actually two different types of flashlights that fall under that label.just now i got http://www.tomtop.com/100-original-ps3-break-modchip-for-sony-ps3-game.html?aid=z PS3 Break Dongle . -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/Problem-with-UART1-on-Davinci-with-OMAP-L138-tp5636641p5637669.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. From billy.chang at camos-multimedia.com Tue Oct 19 06:58:58 2010 From: billy.chang at camos-multimedia.com (Billy Chang) Date: Tue, 19 Oct 2010 13:58:58 +0200 Subject: NAND BOOT FAILUER, Why? Message-ID: <06621F0BB2E74BC8BD62FACBF66FCEF4@bjangdell1310> Hello. I need help for everyone. We have used DM355 for playing video and so on. About 5% of mass production has "NAND Boot Failure". I do "Power Off, on" several times, but I can see this error continuously. At first time, I have changed NAND memory, but the result was same. Change DDR and Change DM355, but the issue could not be cleared. I don't know why this happens. For some board, I have used it in several weeks, it worked well. After that, I met the same issue. Now, I have started to check all other parts such as some serial resistor of 22ohm between DM355 and DDR. If you have any similar problem, would you let me know some solution. Thank you. Pilsun2000. -------------- next part -------------- An HTML attachment was scrubbed... URL: From khilman at deeprootsystems.com Thu Oct 21 14:09:43 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 21 Oct 2010 12:09:43 -0700 Subject: [PATCH v2 00/12] tnetv107x ssp driver stack In-Reply-To: <1287429922-18870-1-git-send-email-cyril@ti.com> (Cyril Chemparathy's message of "Mon, 18 Oct 2010 15:25:10 -0400") References: <1287429922-18870-1-git-send-email-cyril@ti.com> Message-ID: <87fwvzuzuw.fsf@deeprootsystems.com> Cyril Chemparathy writes: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). Hi Cyril, Can you do one more posting, including the acks from the subsystem maintainers so far, and posting also to LKML and linux-arm-kernel at lists.infradead.org. Also the backlight driver needs a review/ack from Richard Purdie (search for drivers/video/backlight in MAINTAINERS). With acks from all the subsystem maintainers, I think it makes sense to merge all of these together via the davinci tree. At the moment, I'm not sure who the final authority on the drivers/misc stuff is, but I will ask in response to your updated posting. Thanks, Kevin > This patch series implements a driver stack that looks like the following: > > +--------+ > | eeprom | . . . > +--------+ > +-----------+ +--------------+ +---------+ > | regulator | . . . | i2c-gpio | | 1-wire | . . . > +-----------+ +--------------+ +---------+ > +----------------------+ +--------------------------------+ > | ssp-spi | | ssp-gpio | > +----------------------+ +--------------------------------+ > +----------------------------------------------------------+ > | ssp | > +----------------------------------------------------------+ > > > Changes between v1 and v2 of this series: > > - Replaced open()/close() semantics with dynamic platform_device > registration on SSP probe. > > - Removed user-land interface to regulator registers > > - More sensible regulator constraints > > - Other minor cleanups > > > Cyril Chemparathy (12): > misc: add driver for sequencer serial port > davinci: add tnetv107x ssp platform device > davinci: add ssp config for tnetv107x evm board > spi: add ti-ssp spi master driver > davinci: add spi devices on tnetv107x evm > regulator: add driver for tps6524x regulator > davinci: add tnetv107x evm regulators > gpio: add ti-ssp virtual gpio driver > davinci: add tnetv107x evm ti-ssp gpio device > backlight: add support for tps6116x controller > davinci: add tnetv107x evm backlight device > davinci: add tnetv107x evm i2c eeprom device > > arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ > arch/arm/mach-davinci/devices-tnetv107x.c | 25 + > arch/arm/mach-davinci/include/mach/ti_ssp.h | 99 ++++ > arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + > arch/arm/mach-davinci/tnetv107x.c | 2 +- > drivers/gpio/Kconfig | 10 + > drivers/gpio/Makefile | 1 + > drivers/gpio/ti-ssp-gpio.c | 200 +++++++ > drivers/misc/Kconfig | 11 + > drivers/misc/Makefile | 1 + > drivers/misc/ti_ssp.c | 436 +++++++++++++++ > drivers/regulator/Kconfig | 10 + > drivers/regulator/Makefile | 1 + > drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ > drivers/spi/Kconfig | 6 + > drivers/spi/Makefile | 1 + > drivers/spi/spi_ti_ssp.c | 397 ++++++++++++++ > drivers/video/backlight/Kconfig | 7 + > drivers/video/backlight/Makefile | 2 +- > drivers/video/backlight/tps6116x.c | 340 ++++++++++++ > 20 files changed, 2440 insertions(+), 2 deletions(-) > create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h > create mode 100644 drivers/gpio/ti-ssp-gpio.c > create mode 100644 drivers/misc/ti_ssp.c > create mode 100644 drivers/regulator/tps6524x-regulator.c > create mode 100644 drivers/spi/spi_ti_ssp.c > create mode 100644 drivers/video/backlight/tps6116x.c > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From khilman at deeprootsystems.com Thu Oct 21 14:12:12 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 21 Oct 2010 12:12:12 -0700 Subject: How to reply a tested by for a patch In-Reply-To: (Rene Gonzalez's message of "Tue, 19 Oct 2010 15:38:22 -0500") References: Message-ID: <87aam7uzqr.fsf@deeprootsystems.com> Rene Gonzalez writes: > Hi all, > I'm very new in kernel stuffs so; > I have applied a set of patches for a hawkboard-L138 and I wonder if there is > specific format for > reply a tested by. Should? I add comments about the way I tested or just I > reply it > by adding a "tested by" headline? First, thanks for doing the testing and reporting your results. It is much appreciated. In the future, when testing whole series, you can just reply to the 'PATCH 0/x' introduction with your Tested-by: and some brief details on how/what you tested. Thanks, Kevin From khilman at deeprootsystems.com Thu Oct 21 14:17:27 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 21 Oct 2010 12:17:27 -0700 Subject: [PATCH 0/2] davinci: clock control fixes In-Reply-To: <1287611397-14974-1-git-send-email-cyril@ti.com> (Cyril Chemparathy's message of "Wed, 20 Oct 2010 17:49:55 -0400") References: <1287611397-14974-1-git-send-email-cyril@ti.com> Message-ID: <87zku7tkxk.fsf@deeprootsystems.com> Cyril Chemparathy writes: > This series applies a few fixes necessary to get tnetv107x hardware > functioning properly. A summary of these fixes follow: > > - davinci: fix sysclk rate setting code to allow for larger divider values > - tnetv107x: reparent tnetv107x usb clocks to usbss > - tnetv107x: mark timer1 as always enabled > - tnetv107x: enable set_rate on pll divider output clocks > - tnetv107x: fix invalid reset defaults on tsc sysclk divider Applied, and queuing for 2.6.38. Thanks, Kevin > Cyril Chemparathy (2): > davinci: use divide ratio limits from pll_data > davinci: minor tnetv107x clock tree fixes > > arch/arm/mach-davinci/clock.c | 4 ++-- > arch/arm/mach-davinci/devices-tnetv107x.c | 15 ++++++++++++++- > arch/arm/mach-davinci/tnetv107x.c | 23 ++++++++++++----------- > 3 files changed, 28 insertions(+), 14 deletions(-) > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From lrg at slimlogic.co.uk Thu Oct 21 15:44:36 2010 From: lrg at slimlogic.co.uk (Liam Girdwood) Date: Thu, 21 Oct 2010 21:44:36 +0100 Subject: [alsa-devel] [PATCH v5 0/9] Add Omapl138-Hawkboard support In-Reply-To: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1287693876.3205.72.camel@odin> On Tue, 2010-10-19 at 13:06 -0500, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > This patch adds > EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI > support for the Hawkboard-L138 system > It is under the machine name "omapl138_hawkboard". > This system is based on the da850 davinci CPU architecture. > > Victor Rodriguez (9): > davinci: EMAC support for Omapl138-Hawkboard > davinci: EDMA support for Omapl138-Hawkboard > davinci: ASoC support for Omapl138-Hawkboard > davinci: McASP configuration for Omapl138-Hawkboard > davinci: Audio support for Omapl138-Hawkboard > davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard > davinci: MMC/SD support for Omapl138-Hawkboar > davinci: USB clocks for Omapl138-Hawkboard > davinci: USB1.1 support for Omapl138-Hawkboard > > arch/arm/mach-davinci/board-omapl138-hawk.c | 317 +++++++++++++++++++++++++++ > arch/arm/mach-davinci/da850.c | 22 ++- > arch/arm/mach-davinci/include/mach/mux.h | 4 + > sound/soc/davinci/Kconfig | 5 +- > sound/soc/davinci/davinci-evm.c | 6 +- > 5 files changed, 349 insertions(+), 5 deletions(-) > ASoC parts :- Acked-by: Liam Girdwood -- Freelance Developer, SlimLogic Ltd ASoC and Voltage Regulator Maintainer. http://www.slimlogic.co.uk From broonie at opensource.wolfsonmicro.com Thu Oct 21 17:28:28 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Thu, 21 Oct 2010 23:28:28 +0100 Subject: [alsa-devel] [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> Message-ID: <20101021222828.GC9346@sirena.org.uk> On Tue, Oct 19, 2010 at 01:06:21PM -0500, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > This patch adds ASoC support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez Acked-by: Mark Brown Please do remember to CC maintainers on patches so they see them. From david-b at pacbell.net Thu Oct 21 17:41:22 2010 From: david-b at pacbell.net (David Brownell) Date: Thu, 21 Oct 2010 15:41:22 -0700 Subject: [PATCH v2 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287429922-18870-9-git-send-email-cyril@ti.com> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-9-git-send-email-cyril@ti.com> Message-ID: <1287700882.2038.135.camel@helium> On Mon, 2010-10-18 at 15:25 -0400, Cyril Chemparathy wrote: > This patch adds a GPIO driver based on TI's SSP device. This driver does not > support GPIO-IRQs. Doesn't look particularly evil, except I don't much like the notion of needing a "stack" if it's not being used like an MFD where numerous functions are accessed concurrently, better IMO to just have each function's driver bind exclusively to the chip (and drive it in the mode it supports -- SPI, GPIO etc). Also, the patch description is weak/confusing. First, there's not a thing "virtual" about this. Second, just say that this GPIO driver is bypassing pretty much everything in the SSP module (notably, all the silicon support for serial protocols) and just driving some of the pins as GPIOs. (Right?) > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/include/mach/ti_ssp.h | 4 + > drivers/gpio/Kconfig | 10 ++ > drivers/gpio/Makefile | 1 + > drivers/gpio/ti-ssp-gpio.c | 200 +++++++++++++++++++++++++++ > 4 files changed, 215 insertions(+), 0 deletions(-) > create mode 100644 drivers/gpio/ti-ssp-gpio.c > > diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h > index 63c88fe..21f1429 100644 > --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h > +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h > @@ -39,6 +39,10 @@ struct ti_ssp_spi_data { > void (*select)(int cs); > }; > > +struct ti_ssp_gpio_data { > + int start; > +}; > + > /* > * Sequencer port IO pin configuration bits. These do not correlate 1-1 with > * the hardware. The iosel field in the port data combines iosel1 and iosel2, > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 510aa20..e400761 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -111,6 +111,16 @@ config GPIO_SCH > This driver can also be built as a module. If so, the module > will be called sch-gpio. > > +config GPIO_TI_SSP > + tristate "TI SSP Controller GPIO Driver" > + depends on GPIOLIB && TI_SSP > + help > + Say yes here to support a virtual GPIO interface on TI SSP ports. > + Each SSP port translates into 4 GPIOs, with no IRQ support. Don't emphasize the "no IRQ part so much; lots of GPIOs don't do IRQs. If a board uses SSP this way, it won't care; Kconfig users have no control over such board wiring issues. > + > + This driver can also be built as a module. If so, the module > + will be called ti-ssp-gpio. > + > comment "I2C GPIO expanders:" > > config GPIO_MAX7300 > diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile > index fc6019d..98b4551 100644 > --- a/drivers/gpio/Makefile > +++ b/drivers/gpio/Makefile > @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o > obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o > obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o > obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o > +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o > obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o > obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o > obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o > diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c > new file mode 100644 > index 0000000..c046713 > --- /dev/null > +++ b/drivers/gpio/ti-ssp-gpio.c > @@ -0,0 +1,200 @@ > +/* > + * Sequencer Serial Port (SSP) based virtual GPIO driver > + * > + * Copyright (C) 2010 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +struct ti_ssp_gpio { > + struct gpio_chip chip; > +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) > + struct device *dev; > + spinlock_t lock; > + u8 out; > + u32 iosel; > +}; > + > +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int error = 0; > + > + spin_lock(&gpio->lock); > + > + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); > + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); > + > + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); > + > + spin_unlock(&gpio->lock); > + > + return error; > +} > + > +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int error; > + > + spin_lock(&gpio->lock); > + > + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); > + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); > + > + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); > + > + if (error < 0) > + goto error; > + > + if (val) > + gpio->out |= BIT(gpio_num); > + else > + gpio->out &= ~BIT(gpio_num); > + > + error = ti_ssp_raw_write(gpio->dev, gpio->out); > + > +error: > + spin_unlock(&gpio->lock); > + return error; > +} > + > +static int value_get(struct gpio_chip *chip, unsigned gpio_num) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + int ret; > + > + spin_lock(&gpio->lock); > + > + ret = ti_ssp_raw_read(gpio->dev); > + if (ret >= 0) > + ret = (ret & BIT(gpio_num)) ? 1 : 0; > + > + spin_unlock(&gpio->lock); > + return ret; > +} > + > +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) > +{ > + struct ti_ssp_gpio *gpio = chip2gpio(chip); > + > + spin_lock(&gpio->lock); > + > + if (val) > + gpio->out |= BIT(gpio_num); > + else > + gpio->out &= ~BIT(gpio_num); > + > + ti_ssp_raw_write(gpio->dev, gpio->out); > + > + spin_unlock(&gpio->lock); > +} > + > +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) > +{ > + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; > + struct device *dev = &pdev->dev; > + struct ti_ssp_gpio *gpio; > + int error; > + > + if (!pdata) { > + dev_err(dev, "platform data not found\n"); > + return -EINVAL; > + } > + > + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); > + if (!gpio) { > + dev_err(dev, "cannot allocate driver data\n"); > + return -ENOMEM; > + } > + > + gpio->dev = dev; > + gpio->iosel = SSP_PIN_SEL(0, SSP_IN) | SSP_PIN_SEL(1, SSP_IN) | > + SSP_PIN_SEL(2, SSP_IN) | SSP_PIN_SEL(3, SSP_IN); > + spin_lock_init(&gpio->lock); > + platform_set_drvdata(pdev, gpio); > + > + gpio->chip.base = pdata->start; > + gpio->chip.ngpio = 4; > + gpio->chip.dev = &pdev->dev; > + gpio->chip.label = "ti_ssp_gpio"; > + gpio->chip.owner = THIS_MODULE; > + gpio->chip.get = value_get; > + gpio->chip.set = value_set; > + gpio->chip.direction_input = direction_in; > + gpio->chip.direction_output = direction_out; > + > + error = gpiochip_add(&gpio->chip); > + if (error < 0) { > + dev_err(dev, "gpio chip registration failed (%d)\n", error); > + goto error; > + } > + > + dev_info(dev, "ssp gpio interface registered\n"); > + return 0; > + > +error: > + kfree(gpio); > + return error; > +} > + > +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) > +{ > + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); > + int error; > + > + error = gpiochip_remove(&gpio->chip); > + if (error < 0) > + return error; > + kfree(gpio); > + return 0; > +} > + > +static struct platform_driver ti_ssp_gpio_driver = { > + .probe = ti_ssp_gpio_probe, > + .remove = __devexit_p(ti_ssp_gpio_remove), > + .driver = { > + .name = "ti-ssp-gpio", > + .owner = THIS_MODULE, > + }, > +}; > + > +static int __init ti_ssp_gpio_init(void) > +{ > + return platform_driver_register(&ti_ssp_gpio_driver); > +} > +subsys_initcall(ti_ssp_gpio_init); > + > +static void __exit ti_ssp_gpio_exit(void) > +{ > + platform_driver_unregister(&ti_ssp_gpio_driver); > +} > +module_exit(ti_ssp_gpio_exit); > + > +MODULE_DESCRIPTION("GPIO interface for TI-SSP"); > +MODULE_AUTHOR("Cyril Chemparathy "); > +MODULE_LICENSE("GPL"); > +MODULE_ALIAS("platform:ti-ssp-gpio"); From cyril at ti.com Thu Oct 21 18:40:44 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 19:40:44 -0400 Subject: [PATCH v2 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287700882.2038.135.camel@helium> References: <1287429922-18870-1-git-send-email-cyril@ti.com> <1287429922-18870-9-git-send-email-cyril@ti.com> <1287700882.2038.135.camel@helium> Message-ID: <4CC0CF7C.1030908@ti.com> Hi David, On 10/21/2010 06:41 PM, David Brownell wrote: > On Mon, 2010-10-18 at 15:25 -0400, Cyril Chemparathy wrote: >> This patch adds a GPIO driver based on TI's SSP device. This driver does not >> support GPIO-IRQs. > > Doesn't look particularly evil, except I don't much like the notion of > needing a "stack" if it's not being used like an MFD where numerous > functions are accessed concurrently, better IMO to just have each > function's driver bind exclusively to the chip (and drive it in the > mode it supports -- SPI, GPIO etc). SPI and GPIO are not the only modes that this hardware can be programmed to behave in. In future, other functions may be added as needed. I thought it would be best to keep the shared stuff reusable. > Also, the patch description is weak/confusing. First, there's not a > thing "virtual" about this. Second, just say that this GPIO driver is > bypassing pretty much everything in the SSP module (notably, all the > silicon support for serial protocols) and just driving some of the > pins as GPIOs. (Right?) Sure. [...] >> +config GPIO_TI_SSP >> + tristate "TI SSP Controller GPIO Driver" >> + depends on GPIOLIB && TI_SSP >> + help >> + Say yes here to support a virtual GPIO interface on TI SSP ports. >> + Each SSP port translates into 4 GPIOs, with no IRQ support. > > Don't emphasize the "no IRQ part so much; lots of GPIOs don't do IRQs. > If a board uses SSP this way, it won't care; Kconfig users have no > control over such board wiring issues. Agreed. Thanks Cyril. From david-b at pacbell.net Thu Oct 21 19:00:53 2010 From: david-b at pacbell.net (David Brownell) Date: Thu, 21 Oct 2010 17:00:53 -0700 (PDT) Subject: [PATCH v2 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <4CC0CF7C.1030908@ti.com> Message-ID: <72577.70502.qm@web180304.mail.gq1.yahoo.com> > > Doesn't look particularly evil, except I don't much > like the notion of > > needing a "stack" if it's not being used > like an MFD where numerous > > functions are accessed concurrently, > better IMO to just have each function's driver bind exclusively to the chip (and > drive it in the > > mode it supports -- SPI, GPIO etc). > > SPI and GPIO are not the only modes that > this hardware can be programmed I know; ergo the "etc". This is common for serial engines. Many have enough flexibility to hook up to several flavors of audio codec too. > to behave in.? In future, other functions may be added > as needed.? And each one would have its own driver. > I thought it would be best to keep the > shared stuff reusable. The way I've seen that done in the past is to keep the register decls clean enough so most drivers use them directly ... and in a few cases, provide some library code (if there is a a good reason to share any logic). (But it often turned out that the functions couldn't share much beyond the register layouts, since behaviors of each function differ so widely. > ? > there's not a > > thing "virtual" about this. From claudiacrb at gmail.com Fri Oct 22 09:28:34 2010 From: claudiacrb at gmail.com (Claudia Rodriguez Brasicott) Date: Fri, 22 Oct 2010 09:58:34 -0430 Subject: general steps to configure a platform device in DA830/OMAP-L137 Message-ID: Hello, I'm trying to configure a eqep device in a DA830 board with Arago Community Linux installed. I don't have much experience working with drivers, so if you can give me some guidelines to do it, I'll be very grateful. Thanks! -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Fri Oct 22 09:44:25 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Fri, 22 Oct 2010 09:44:25 -0500 Subject: [alsa-devel] [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> Message-ID: On Fri, Oct 22, 2010 at 2:22 AM, Jassi Brar wrote: > Hi Victor, > > Excuse me for slightly off-topic issue. > > Assuming your Hawkboard is the one -> http://elinux.org/Hawkboard/BeginnersGuide > > It randomly and very frequently hangs while booting. Something very > similar to as mentioned by people in > ?http://groups.google.com/group/hawkboard/browse_thread/thread/5c21748e09f3c45a > > Can you please confirm if it is just the u-boot and kernel images from the site > that cause these problems, because apparently you are using the board just fine. HI Jassi, the problem is described on Khasim message http://groups.google.com/group/hawkboard/browse_thread/thread/77be8314136d752d And in the end clarify [.....] The new lot of hawkboards have DDR part changed to "Commercial version" earlier it was "Industrial version" - If your board has D9KSF then it is Industrial version - If your board has D9LHR then it is Commercial version. The refresh timing for these devices are different. The fix is not in kernel, it has to be done in AIS while signing the u-boot. When you follow the procedure to sign the u-boot http://elinux.org/Hawkboard#Signing_u-boot_for_UART_boot If you have a D9LHR memory on board then give SDRCR as 0x492. Sign your u-boot with other settings as given and follow the instructions on the same page to flash the NAND. This should fix all the issues w.r.t "Starting Kernel ... " hangs with new lot of boards (memory). [.....] I will upload a pre-built u-boot for NAND and UART boot soon, also update the wiki. Please try this out and let me know your inputs. [.....] My board work fine with the pre compiled u-boot because the time was produced. I started to work with it on July when the u-boot and kernel images from the site worked fine, Now like Khasim said the hardware has change, but this week, the thread that you send me are from one week ago. Besides Sughosh Ganu is working on u-boot for Hawkboard as well as Khasim. This is u-boot problem not from kernel. > Also, could you please point me to latest working source codes for > U-boot and kernel? I do not know the latest from u-boot sorry, but for the kernel is the latest. This series of patches apply fine And besides they have been tested by some one else with out any complaint :) Sorry if the recently hangs on treads cause confusion but is something different for the kernel support Regards Sincerely yours Victor Rodriguez > Thanks and Regards. > From amraldo at hotmail.com Mon Oct 25 03:23:33 2010 From: amraldo at hotmail.com (amr ali) Date: Mon, 25 Oct 2010 10:23:33 +0200 Subject: Gnash on TI Message-ID: Did anyone try running on Gnash on DM6446 or any similar package for supporting flash? -- Amr Ali Abdel-Naby Embedded Systems Developer www.embedded-tips.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From hebert.marcandre at gmail.com Mon Oct 25 07:09:27 2010 From: hebert.marcandre at gmail.com (=?ISO-8859-1?Q?Marc=2DAndr=E9_H=E9bert?=) Date: Mon, 25 Oct 2010 08:09:27 -0400 Subject: Problem with new SPI driver Message-ID: Hi, I would have replied directly to the original thread but I wasn't on the mailing list back then. I wanted to report I encountered some problems using the [PATCH v5 1/1] davinci: spi: replace existing driver. I am currently using the Arago tree. I also applied the required DMA patch (http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2010-March/018022.html). I will try to test with linux-davinci but for that I would need more work on the omapl138 spi first. Reading a block of at least 64k of data does not work with the new driver. Here is how I reproduced (/dev/mtd1 is a spi flash with 256KB sector size): dd if=/dev/mtd1 of=/dev/null count=1bs=32768 #OK dd if=/dev/mtd1 of=/dev/null count=2bs=32768 #OK dd if=/dev/mtd1 of=/dev/null count=1bs=65536 #Stalls in davinci_spi_txrx_bufs Trying with a block size of 128KB also fails. I am just unsure if this failure is due to me using the Arago tree (maybe something else is missing) or this is really an issue with the driver. If anybody else can confirm or deny, it would be great. Regards Marc From hebert.marcandre at gmail.com Mon Oct 25 07:30:14 2010 From: hebert.marcandre at gmail.com (=?ISO-8859-1?Q?Marc=2DAndr=E9_H=E9bert?=) Date: Mon, 25 Oct 2010 08:30:14 -0400 Subject: Problem with new SPI driver In-Reply-To: References: Message-ID: 2010/10/25 Marc-Andr? H?bert : > Hi, > > I would have replied directly to the original thread but I wasn't on > the mailing list back then. I wanted to report I encountered some > problems using the [PATCH v5 1/1] davinci: spi: replace existing > driver. > > I am currently using the Arago tree. I also applied the required DMA > patch (http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2010-March/018022.html). > I will try to test with linux-davinci but for that I would need more > work on the omapl138 spi first. > > Reading a block of at least 64k of data does not work with the new > driver. Here is how I reproduced (/dev/mtd1 is a spi flash with 256KB > sector size): > > dd if=/dev/mtd1 of=/dev/null count=1bs=32768 #OK > dd if=/dev/mtd1 of=/dev/null count=2bs=32768 #OK > dd if=/dev/mtd1 of=/dev/null count=1bs=65536 #Stalls in davinci_spi_txrx_bufs > > Trying with a block size of 128KB also fails. I am just unsure if this > failure is due to me using the Arago tree (maybe something else is > missing) or this is really an issue with the driver. If anybody else > can confirm or deny, it would be great. > > Regards > Marc > Think I identified part of the problem (from davinci_spi_txrx_bufs in driver/spi/davinci_spi.c): tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; With my example wcount equals the bs argument. So there is no way this can work if wcount requires more than 16 bits. Is the edma supposed to be limited to transfers with a len of 16 bits or less? Is the spi driver supposed to split the transfers or is there another way to set higher len bits? Marc From nikai at nikai.net Mon Oct 25 07:41:18 2010 From: nikai at nikai.net (Nicolas Kaiser) Date: Mon, 25 Oct 2010 14:41:18 +0200 Subject: [PATCH] davinci: simplify if-statement Message-ID: <20101025144118.62ec420c@absol.kitzblitz> A common do-while loop can be factored out from the end of the branches. Signed-off-by: Nicolas Kaiser --- arch/arm/mach-davinci/psc.c | 13 ++++--------- 1 files changed, 4 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 1b15dbd..a415804 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -83,21 +83,16 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, pdctl1 = __raw_readl(psc_base + PDCTL1); pdctl1 |= 0x100; __raw_writel(pdctl1, psc_base + PDCTL1); - - do { - ptstat = __raw_readl(psc_base + - PTSTAT); - } while (!(((ptstat >> domain) & 1) == 0)); } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); - - do { - ptstat = __raw_readl(psc_base + PTSTAT); - } while (!(((ptstat >> domain) & 1) == 0)); } do { + ptstat = __raw_readl(psc_base + PTSTAT); + } while (!(((ptstat >> domain) & 1) == 0)); + + do { mdstat = __raw_readl(psc_base + MDSTAT + 4 * id); } while (!((mdstat & MDSTAT_STATE_MASK) == next_state)); -- 1.7.2.2 From nsekhar at ti.com Mon Oct 25 10:00:37 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 25 Oct 2010 20:30:37 +0530 Subject: Problem with new SPI driver In-Reply-To: References: Message-ID: Hi Marc-Andr?, On Mon, Oct 25, 2010 at 18:00:14, Marc-Andr? H?bert wrote: > 2010/10/25 Marc-Andr? H?bert : > > Hi, > > > > I would have replied directly to the original thread but I wasn't on > > the mailing list back then. I wanted to report I encountered some > > problems using the [PATCH v5 1/1] davinci: spi: replace existing > > driver. > > > > I am currently using the Arago tree. I also applied the required DMA > > patch (http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2010-March/018022.html). > > I will try to test with linux-davinci but for that I would need more > > work on the omapl138 spi first. > > > > Reading a block of at least 64k of data does not work with the new > > driver. Here is how I reproduced (/dev/mtd1 is a spi flash with 256KB > > sector size): > > > > dd if=/dev/mtd1 of=/dev/null count=1bs=32768 #OK > > dd if=/dev/mtd1 of=/dev/null count=2bs=32768 #OK > > dd if=/dev/mtd1 of=/dev/null count=1bs=65536 #Stalls in davinci_spi_txrx_bufs > > > > Trying with a block size of 128KB also fails. I am just unsure if this > > failure is due to me using the Arago tree (maybe something else is > > missing) or this is really an issue with the driver. If anybody else > > can confirm or deny, it would be great. > > > > Regards > > Marc > > > Think I identified part of the problem (from davinci_spi_txrx_bufs in > driver/spi/davinci_spi.c): > tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; > > With my example wcount equals the bs argument. So there is no way this > can work if wcount requires more than 16 bits. > Is the edma supposed to be limited to transfers with a len of 16 bits > or less? Is the spi driver supposed to split the transfers or is there > another way to set higher len bits? Good catch! The probable solution would be to use the third dimension (C-count) as well. A-Count is fixed to the number of bytes-per-word so the rest of the length value should be factored into B-count * C-Count. I general, I guess there should be a mechanism for any spi master to specify the maximum transfer it can handle and the spi core should be able to break the spi message into suitable sized transfers. I briefly looked at the spi core and found no evidence of such a facility. I also wonder why this issue showed up only with Brian's patches as the original code seems to use only b-count for transfer length programming as well. Thanks, Sekhar From hebert.marcandre at gmail.com Mon Oct 25 11:00:23 2010 From: hebert.marcandre at gmail.com (=?ISO-8859-1?Q?Marc=2DAndr=E9_H=E9bert?=) Date: Mon, 25 Oct 2010 12:00:23 -0400 Subject: Problem with new SPI driver In-Reply-To: References: Message-ID: On Mon, Oct 25, 2010 at 11:00 AM, Nori, Sekhar wrote: > Hi Marc-Andr?, > > On Mon, Oct 25, 2010 at 18:00:14, Marc-Andr? H?bert wrote: >> 2010/10/25 Marc-Andr? H?bert : >> > Hi, >> > >> > I would have replied directly to the original thread but I wasn't on >> > the mailing list back then. I wanted to report I encountered some >> > problems using the [PATCH v5 1/1] davinci: spi: replace existing >> > driver. >> > >> > I am currently using the Arago tree. I also applied the required DMA >> > patch (http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2010-March/018022.html). >> > I will try to test with linux-davinci but for that I would need more >> > work on the omapl138 spi first. >> > >> > Reading a block of at least 64k of data does not work with the new >> > driver. Here is how I reproduced (/dev/mtd1 is a spi flash with 256KB >> > sector size): >> > >> > dd if=/dev/mtd1 of=/dev/null count=1bs=32768 #OK >> > dd if=/dev/mtd1 of=/dev/null count=2bs=32768 #OK >> > dd if=/dev/mtd1 of=/dev/null count=1bs=65536 #Stalls in davinci_spi_txrx_bufs >> > >> > Trying with a block size of 128KB also fails. I am just unsure if this >> > failure is due to me using the Arago tree (maybe something else is >> > missing) or this is really an issue with the driver. If anybody else >> > can confirm or deny, it would be great. >> > >> > Regards >> > Marc >> > >> Think I identified part of the problem (from davinci_spi_txrx_bufs in >> driver/spi/davinci_spi.c): >> tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; >> >> With my example wcount equals the bs argument. So there is no way this >> can work if wcount requires more than 16 bits. >> Is the edma supposed to be limited to transfers with a len of 16 bits >> or less? Is the spi driver supposed to split the transfers or is there >> another way to set higher len bits? > > Good catch! The probable solution would be to use the third dimension (C-count) > as well. A-Count is fixed to the number of bytes-per-word so the rest of the > length value should be factored into B-count * C-Count. > > I general, I guess there should be a mechanism for any spi master to specify > the maximum transfer it can handle and the spi core should be able to break > the spi message into suitable sized transfers. I briefly looked at the spi > core and found no evidence of such a facility. > > I also wonder why this issue showed up only with Brian's patches as the > original code seems to use only b-count for transfer length programming > as well. > > Thanks, > Sekhar > > I tried a quick fix where for transfers larger than 32K. I fixex bcount to 32K and set ccnt to wcount / 32K. if( davinci_spi->wcount > 0xFFFF ) { if( davinci_spi->wcount & 0x7FFF ) { dev_info(sdev, "larger SPI transfers need to be multiples of 32K\n"); return -EIO; } tx_param.a_b_cnt = 0x8000 << 16 | data_type; tx_param.ccnt = davinci_spi->wcount / 0x8000; } else { tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; tx_param.ccnt = 1; } The transfers don't hang but the data above the first 32K is invalid. Must something different be done to use the ccnt correctly? Given my board has larger spi flash sectors, I would like to have a workaround in the driver instead than making sure all applications use small transfers. Thanks Marc From khilman at deeprootsystems.com Mon Oct 25 12:08:15 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 25 Oct 2010 18:08:15 +0100 Subject: [GIT PULL] davinci updates for 2.6.37 Message-ID: <87sjzukxog.fsf@deeprootsystems.com> Linus, Please pull davinci platform updates for 2.6.37: ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git davinci-for-linus Note that I also merged Russell King's devel branch (which you already merged) in order to fixup some final conflicts. diffstat/shortlog follows for just the davinci specific parts. Thanks, Kevin MAINTAINERS | 4 +- arch/arm/configs/da8xx_omapl_defconfig | 3 + arch/arm/mach-davinci/Kconfig | 76 +- arch/arm/mach-davinci/Makefile | 4 +- arch/arm/mach-davinci/aemif.c | 133 +++ arch/arm/mach-davinci/board-da830-evm.c | 24 +- arch/arm/mach-davinci/board-da850-evm.c | 92 ++- arch/arm/mach-davinci/board-dm365-evm.c | 11 +- arch/arm/mach-davinci/board-dm644x-evm.c | 20 +- arch/arm/mach-davinci/board-dm646x-evm.c | 21 +- arch/arm/mach-davinci/board-mityomapl138.c | 424 +++++++ arch/arm/mach-davinci/board-neuros-osd2.c | 7 +- arch/arm/mach-davinci/board-omapl138-hawk.c | 64 ++ arch/arm/mach-davinci/board-sffsdr.c | 7 +- arch/arm/mach-davinci/board-tnetv107x-evm.c | 56 + arch/arm/mach-davinci/clock.c | 75 ++- arch/arm/mach-davinci/clock.h | 5 + arch/arm/mach-davinci/cpufreq.c | 28 +- arch/arm/mach-davinci/da850.c | 76 +- arch/arm/mach-davinci/devices-da8xx.c | 70 ++- arch/arm/mach-davinci/devices-tnetv107x.c | 50 + arch/arm/mach-davinci/devices.c | 2 +- arch/arm/mach-davinci/dm365.c | 23 +- arch/arm/mach-davinci/dm644x.c | 23 +- arch/arm/mach-davinci/dm646x.c | 22 +- arch/arm/mach-davinci/dma.c | 8 +- arch/arm/mach-davinci/include/mach/aemif.h | 36 + arch/arm/mach-davinci/include/mach/da8xx.h | 7 +- arch/arm/mach-davinci/include/mach/dm365.h | 2 +- arch/arm/mach-davinci/include/mach/dm644x.h | 2 +- arch/arm/mach-davinci/include/mach/dm646x.h | 2 +- arch/arm/mach-davinci/include/mach/nand.h | 6 +- arch/arm/mach-davinci/include/mach/psc.h | 1 + arch/arm/mach-davinci/include/mach/tnetv107x.h | 3 + arch/arm/mach-davinci/include/mach/uncompress.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 11 +- arch/arm/mach-omap2/board-am3517evm.c | 31 +- drivers/input/keyboard/Kconfig | 9 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/tnetv107x-keypad.c | 340 ++++++ drivers/input/touchscreen/Kconfig | 9 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tnetv107x-ts.c | 396 +++++++ drivers/mtd/nand/davinci_nand.c | 61 +- drivers/net/Kconfig | 21 + drivers/net/Makefile | 2 + drivers/net/davinci_cpdma.c | 965 ++++++++++++++++ drivers/net/davinci_cpdma.h | 108 ++ drivers/net/davinci_emac.c | 1338 +++-------------------- drivers/net/davinci_mdio.c | 475 ++++++++ include/linux/davinci_emac.h | 16 +- 51 files changed, 3814 insertions(+), 1359 deletions(-) Cyril Chemparathy (17): Davinci: tnetv107x: retain psc reg base after init davinci: add idcode for tnetv107x rev 1.1/1.2 net: davinci_emac: separate out davinci mdio davinci: add mdio platform devices omap: add mdio platform devices net: davinci_emac: switch to new mdio davinci: cleanup mdio arch code and switch to phy_id omap: cleanup unused davinci mdio arch code net: davinci_emac: cleanup unused mdio emac code net: davinci_emac: separate out cpdma code net: davinci_emac: switch to new cpdma layer net: davinci_emac: cleanup unused cpdma code input: add driver for tnetv107x on-chip keypad controller davinci: add tnetv107x keypad platform device davinci: add keypad config for tnetv107x evm board input: add driver for tnetv107x touchscreen controller davinci: add tnetv107x touchscreen platform device Juha Kuikka (3): DA850: Add LPSC id for MMCSD1 peripheral DA850: Split MMCSD clock into two to support both MMCSD peripherals DA850: Add MMCSD1 resources, platform device and convenience registration function Kevin Hilman (1): davinci: clock: make 'disable unused clocks' printk debug only Kulikov Vasiliy (1): arm: mach-davinci: check irq2ctlr() result Michael Williamson (5): davinci: Add machine checks to DA8XX serial console init routines davinci: Add CONFIG_REGULATOR_DUMMY to DA8XX defconfig file. davinci: Initial support for MityDSP-L138/MityARM-1808 davinci: Add I2C0 devices to MityDSP-L138/MityARM-1808 platform davinci: MityDSP-L138/MityARM-1808 read MAC address from I2C Prom Nicolas Kaiser (1): arm/davinci: remove duplicated include Sekhar Nori (17): davinci: da850 evm: sparse cleanup: make file local variables static MAINTAINERS: Add Kevin's e-mail in entry for TI DaVinci davinci: cpufreq: bailout on regulator errors davinci: clean up inconsistent usage of spaces in Kconfig davinci: introduce support for AM1x ARM9 microprocessors davinci: am18x/da850/omap-l138: use 'NOM' voltage defined in datasheet as min voltage davinci: dm365: disable pulldowns for all MMC/SD1 pins. davinci: clock: add support for setting sysclk rate davinci: cpufreq: add support for keeping an additional clock constant davinci: am18x/da850/omap-l138: keep async clock constant with cpufreq davinci: dm365 evm: use EDMAQ_3 as the audio DMA queue davinci: add support for aemif timing configuration nand: davinci: add support for timing configuration davinci: dm644x evm: setup NAND flash timing davinci: am18x/da850/omap-l138 evm: setup NAND flash timing davinci: dm6467t evm: setup NAND flash timing davinci: mityomapl138: make file local data static Sergei Shtylyov (2): DA850: move NAND/NOR pin lists to the board file DA850: move MII/RMII pin lists to the board file Sudhakar Rajashekhara (1): davinci: am17x/da830/omap-l137 evm: setup NAND flash timing Victor Rodriguez (1): davinci: Initial support for Omapl138-Hawkboard From ottavio.campana at dei.unipd.it Tue Oct 26 03:01:29 2010 From: ottavio.campana at dei.unipd.it (Ottavio Campana) Date: Tue, 26 Oct 2010 10:01:29 +0200 Subject: what about DM368 and TMS320C6A8167? Message-ID: <4CC68AD9.6090804@dei.unipd.it> how are they supported by the git tree? Ottavio From cyril at ti.com Thu Oct 21 16:01:02 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:02 -0400 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-2-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch adds a driver for this controller device. The driver does not expose a user-land interface. Protocol drivers built on top of this layer are expected to remain in-kernel. Acked-by: Grant Likely Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 89 ++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 436 +++++++++++++++++++++++++++ 4 files changed, 537 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/misc/ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h new file mode 100644 index 0000000..51afc42 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -0,0 +1,89 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TI_SSP_H__ +#define __TI_SSP_H__ + +struct ti_ssp_dev_data { + const char *dev_name; + unsigned long iosel; /* see note below */ + unsigned long config; + const void *pdata; + int pdata_sz; +}; + +struct ti_ssp_data { + unsigned long out_clock; + struct ti_ssp_dev_data dev_data[2]; +}; + +/* + * Sequencer port IO pin configuration bits. These do not correlate 1-1 with + * the hardware. The iosel field in the port data combines iosel1 and iosel2, + * and is therefore not a direct map to register space. It is best to use the + * macros below to construct iosel values. + * + * least significant 16 bits --> iosel1 + * most significant 16 bits --> iosel2 + */ + +#define SSP_IN 0x0000 +#define SSP_DATA 0x0001 +#define SSP_CLOCK 0x0002 +#define SSP_CHIPSEL 0x0003 +#define SSP_OUT 0x0004 +#define SSP_PIN_SEL(pin, v) ((v) << ((pin) * 3)) +#define SSP_PIN_MASK(pin) SSP_PIN_SEL(pin, 0x7) +#define SSP_INPUT_SEL(pin) ((pin) << 16) + +/* Sequencer port config bits */ +#define SSP_EARLY_DIN BIT(8) +#define SSP_DELAY_DOUT BIT(9) + +/* Sequence map definitions */ +#define SSP_CLK_HIGH BIT(0) +#define SSP_CLK_LOW 0 +#define SSP_DATA_HIGH BIT(1) +#define SSP_DATA_LOW 0 +#define SSP_CS_HIGH BIT(2) +#define SSP_CS_LOW 0 +#define SSP_OUT_MODE BIT(3) +#define SSP_IN_MODE 0 +#define SSP_DATA_REG BIT(4) +#define SSP_ADDR_REG 0 + +#define SSP_OPCODE_DIRECT ((0x0) << 5) +#define SSP_OPCODE_TOGGLE ((0x1) << 5) +#define SSP_OPCODE_SHIFT ((0x2) << 5) +#define SSP_OPCODE_BRANCH0 ((0x4) << 5) +#define SSP_OPCODE_BRANCH1 ((0x5) << 5) +#define SSP_OPCODE_BRANCH ((0x6) << 5) +#define SSP_OPCODE_STOP ((0x7) << 5) +#define SSP_BRANCH(addr) ((addr) << 8) +#define SSP_COUNT(cycles) ((cycles) << 8) + +int ti_ssp_raw_read(struct device *dev); +int ti_ssp_raw_write(struct device *dev, u32 val); +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len); +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output); +int ti_ssp_set_mode(struct device *dev, int mode); +int ti_ssp_set_iosel(struct device *dev, u32 iosel); + +#endif /* __TI_SSP_H__ */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..9fb8470 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -390,6 +390,17 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. +config TI_SSP + depends on ARCH_DAVINCI_TNETV107X + tristate "Sequencer Serial Port support" + default y + ---help--- + Say Y here if you want support for the Sequencer Serial Port + in a Texas Instruments TNETV107X SoC. + + To compile this driver as a module, choose M here: the + module will be called ti_ssp. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..7568100 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o +obj-$(CONFIG_TI_SSP) += ti_ssp.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o diff --git a/drivers/misc/ti_ssp.c b/drivers/misc/ti_ssp.c new file mode 100644 index 0000000..8249a8b --- /dev/null +++ b/drivers/misc/ti_ssp.c @@ -0,0 +1,436 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Register Offsets */ +#define REG_REV 0x00 +#define REG_IOSEL_1 0x04 +#define REG_IOSEL_2 0x08 +#define REG_PREDIV 0x0c +#define REG_INTR_ST 0x10 +#define REG_INTR_EN 0x14 +#define REG_TEST_CTRL 0x18 + +/* Per port registers */ +#define PORT_CFG_2 0x00 +#define PORT_ADDR 0x04 +#define PORT_DATA 0x08 +#define PORT_CFG_1 0x0c +#define PORT_STATE 0x10 + +#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) +#define SSP_PORT_CLKRATE_MASK 0x0f + +#define SSP_SEQRAM_WR_EN BIT(4) +#define SSP_SEQRAM_RD_EN BIT(5) +#define SSP_START BIT(15) +#define SSP_BUSY BIT(10) +#define SSP_PORT_ASL BIT(7) +#define SSP_PORT_CFO1 BIT(6) + +#define SSP_PORT_SEQRAM_SIZE 32 + +static const int ssp_port_base[] = {0x040, 0x080}; +static const int ssp_port_seqram[] = {0x100, 0x180}; + +struct ti_ssp { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; + struct clk *clk; + const struct ti_ssp_data *data; +}; + +#define dev2ssp(dev) dev_get_drvdata(dev->parent) +#define dev2port(dev) (to_platform_device(dev)->id) + +/* Register Access Helpers */ +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) +{ + return __raw_readl(ssp->regs + reg); +} + +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) +{ + __raw_writel(val, ssp->regs + reg); +} + +static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) +{ + u32 val = ssp_read(ssp, reg); + val &= ~mask; + val |= bits; + ssp_write(ssp, reg, val); +} + +static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg) +{ + return ssp_read(ssp, ssp_port_base[port] + reg); +} + +static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg, + u32 val) +{ + ssp_write(ssp, ssp_port_base[port] + reg, val); +} + +static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg, + u32 mask, u32 bits) +{ + ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits); +} + +static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, bits, 0); +} + +static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, 0, bits); +} + +static int __set_mode(struct ti_ssp *ssp, int port, int mode) +{ + mode &= SSP_PORT_CONFIG_MASK; + ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode); + + return 0; +} + +int ti_ssp_set_mode(struct device *dev, int mode) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_mode(ssp, port, mode); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_mode); + +static int __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) +{ + unsigned val; + + /* IOSEL1 gets the least significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_1); + val &= 0xffff << (port ? 0 : 16); + val |= (iosel & 0xffff) << (port ? 16 : 0); + ssp_write(ssp, REG_IOSEL_1, val); + + /* IOSEL2 gets the most significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_2); + val &= 0x0007 << (port ? 0 : 16); + val |= (iosel & 0x00070000) >> (port ? 0 : 16); + ssp_write(ssp, REG_IOSEL_2, val); + + return 0; +} + +int ti_ssp_set_iosel(struct device *dev, u32 iosel) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_iosel(ssp, port, iosel); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_iosel); + +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int i; + + if (len > SSP_PORT_SEQRAM_SIZE) + return -ENOSPC; + + spin_lock(&ssp->lock); + + /* Enable SeqRAM access */ + ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + /* Copy code */ + for (i = 0; i < len; i++) { + __raw_writel(prog[i], ssp->regs + offs + 4*i + + ssp_port_seqram[port]); + } + + /* Disable SeqRAM access */ + ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_load); + +int ti_ssp_raw_read(struct device *dev) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + u32 val; + + val = ssp_read(ssp, REG_IOSEL_2); + val >>= (port ? 27 : 11); + + return val & 0x0f; +} +EXPORT_SYMBOL(ti_ssp_raw_read); + +int ti_ssp_raw_write(struct device *dev, u32 val) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + u32 mask; + + spin_lock(&ssp->lock); + val &= 0x0f; + val <<= (port ? 22 : 6); + mask = 0x0f; + mask <<= (port ? 22 : 6); + ssp_rmw(ssp, REG_IOSEL_2, mask, val); + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_raw_write); + +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) +{ + struct ti_ssp *ssp = dev2ssp(dev); + int port = dev2port(dev); + int count; + + if (pc & ~(0x3f)) + return -EINVAL; + + ssp_port_write(ssp, port, PORT_ADDR, input >> 16); + ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); + ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); + + ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); + + for (count = 10000; count; count--) { + if ((ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY) == 0) + break; + udelay(1); + } + + if (output) { + *(output) = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | + (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); + } + + if (!count) { + dev_err(ssp->dev, "timed out waiting for SSP operation\n"); + return -EIO; + } + + /* return stop address */ + return ssp_port_read(ssp, port, PORT_STATE) & 0x3f; +} +EXPORT_SYMBOL(ti_ssp_run); + +static int __unregister_subdev(struct device *dev, void *unused) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +static int unregister_subdevs(struct ti_ssp *ssp) +{ + return device_for_each_child(ssp->dev, NULL, __unregister_subdev); +} + +static void register_subdevs(struct ti_ssp *ssp) +{ + int id; + + for (id = 0; id < 2; id++) { + const struct ti_ssp_dev_data *data = &ssp->data->dev_data[id]; + + if (!data->dev_name) + continue; + + spin_lock(&ssp->lock); + __set_iosel(ssp, id, data->iosel); + ssp_port_rmw(ssp, id, PORT_CFG_1, SSP_PORT_CONFIG_MASK, + data->config); + ssp_port_rmw(ssp, id, PORT_CFG_2, SSP_PORT_CLKRATE_MASK, 0); + spin_unlock(&ssp->lock); + + platform_device_register_data(ssp->dev, data->dev_name, id, + data->pdata, data->pdata_sz); + } +} + +static int __devinit ti_ssp_probe(struct platform_device *pdev) +{ + static struct ti_ssp *ssp; + const struct ti_ssp_data *pdata = pdev->dev.platform_data; + int ret = 0, prediv = 0xff; + unsigned long sysclk; + struct device *dev = &pdev->dev; + + ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); + if (!ssp) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + ssp->data = pdata; + ssp->dev = dev; + dev_set_drvdata(dev, ssp); + + ret = -ENODEV; + ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ssp->res) { + dev_err(dev, "cannot determine register area\n"); + goto error_res; + } + + ret = -EINVAL; + if (!request_mem_region(ssp->res->start, resource_size(ssp->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + goto error_res; + } + + ret = -ENOMEM; + ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); + if (!ssp->regs) { + dev_err(dev, "cannot map register memory\n"); + goto error_map; + } + + ret = -EINVAL; + ssp->clk = clk_get(dev, NULL); + if (IS_ERR(ssp->clk)) { + dev_err(dev, "cannot claim device clock\n"); + goto error_clk; + } + + spin_lock_init(&ssp->lock); + + /* Power on and initialize SSP */ + ret = clk_enable(ssp->clk); + if (ret) + goto error_enable; + + /* Reset registers to a sensible known state */ + ssp_write(ssp, REG_IOSEL_1, 0); + ssp_write(ssp, REG_IOSEL_2, 0); + ssp_write(ssp, REG_INTR_EN, 0); + ssp_write(ssp, REG_TEST_CTRL, 0); + ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1); + ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1); + + sysclk = clk_get_rate(ssp->clk); + if (pdata && pdata->out_clock) + prediv = (sysclk / pdata->out_clock) - 1; + prediv = clamp(prediv, 0, 0xff); + ssp_rmw(ssp, REG_PREDIV, 0xff, prediv); + + register_subdevs(ssp); + + return 0; + +error_enable: + clk_put(ssp->clk); +error_clk: + iounmap(ssp->regs); +error_map: + release_mem_region(ssp->res->start, resource_size(ssp->res)); +error_res: + kfree(ssp); + return ret; +} + +static int __devexit ti_ssp_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ti_ssp *ssp = dev_get_drvdata(dev); + + unregister_subdevs(ssp); + clk_disable(ssp->clk); + clk_put(ssp->clk); + iounmap(ssp->regs); + release_mem_region(ssp->res->start, resource_size(ssp->res)); + kfree(ssp); + dev_set_drvdata(dev, NULL); + return 0; +} + +static struct platform_driver ti_ssp_driver = { + .probe = ti_ssp_probe, + .remove = __devexit_p(ti_ssp_remove), + .driver = { + .name = "ti-ssp", + .owner = THIS_MODULE, + } +}; + +static int __init ti_ssp_init(void) +{ + return platform_driver_register(&ti_ssp_driver); +} +arch_initcall_sync(ti_ssp_init); + +static void __exit ti_ssp_exit(void) +{ + platform_driver_unregister(&ti_ssp_driver); +} +module_exit(ti_ssp_exit); + +MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti_ssp"); -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:01 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:01 -0400 Subject: [PATCH v3 00/12] tnetv107x ssp driver stack Message-ID: <1287694873-12904-1-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch series implements a driver stack that looks like the following: +--------+ | eeprom | . . . +--------+ +-----------+ +--------------+ +---------+ | regulator | . . . | i2c-gpio | | 1-wire | . . . +-----------+ +--------------+ +---------+ +----------------------+ +--------------------------------+ | ssp-spi | | ssp-gpio | +----------------------+ +--------------------------------+ +----------------------------------------------------------+ | ssp | +----------------------------------------------------------+ Changes between v2 and v3 of this series: - Minor cleanups in Kconfig and Makefile ordering Changes between v1 and v2 of this series: - Replaced open()/close() semantics with dynamic platform_device registration on SSP probe. - Removed user-land interface to regulator registers - More sensible regulator constraints - Other minor cleanups Cyril Chemparathy (12): misc: add driver for sequencer serial port davinci: add tnetv107x ssp platform device davinci: add ssp config for tnetv107x evm board spi: add ti-ssp spi master driver davinci: add spi devices on tnetv107x evm regulator: add driver for tps6524x regulator davinci: add tnetv107x evm regulators gpio: add ti-ssp virtual gpio driver davinci: add tnetv107x evm ti-ssp gpio device backlight: add support for tps6116x controller davinci: add tnetv107x evm backlight device davinci: add tnetv107x evm i2c eeprom device arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ arch/arm/mach-davinci/devices-tnetv107x.c | 25 + arch/arm/mach-davinci/include/mach/ti_ssp.h | 98 ++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- drivers/gpio/Kconfig | 10 + drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++ drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 436 +++++++++++++++ drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 397 ++++++++++++++ drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++ 20 files changed, 2440 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/gpio/ti-ssp-gpio.c create mode 100644 drivers/misc/ti_ssp.c create mode 100644 drivers/regulator/tps6524x-regulator.c create mode 100644 drivers/spi/spi_ti_ssp.c create mode 100644 drivers/video/backlight/tps6116x.c From cyril at ti.com Thu Oct 21 16:01:04 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:04 -0400 Subject: [PATCH v3 03/12] davinci: add ssp config for tnetv107x evm board In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-4-git-send-email-cyril@ti.com> This patch adds SSP configuration and pin muxing info for tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 5afa8fc..401ad26 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define EVM_MMC_WP_GPIO 21 @@ -99,6 +100,12 @@ static const short uart1_pins[] __initdata = { -1 }; +static const short ssp_pins[] __initdata = { + TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, + TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, + TNETV107X_SSP1_3, -1 +}; + static struct mtd_partition nand_partitions[] = { /* bootloader (U-Boot, etc) in first 12 sectors */ { @@ -196,17 +203,25 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static struct ti_ssp_data ssp_config = { + .out_clock = 250 * 1000, + .dev_data = { + }, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ .keypad_config = &keypad_config, + .ssp_config = &ssp_config, }; static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); davinci_cfg_reg_list(uart1_pins); + davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); } -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:03 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:03 -0400 Subject: [PATCH v3 02/12] davinci: add tnetv107x ssp platform device In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-3-git-send-email-cyril@ti.com> This patch adds an SSP platform device definition for the tnetv107x soc family. The clock lookup entry has also been updated to match. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 25 ++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index c9a86d8..2c7aa5f 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -35,6 +35,7 @@ #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 +#define TNETV107X_SSP_BASE 0x08088c00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 @@ -342,6 +343,25 @@ static struct platform_device tsc_device = { .resource = tsc_resources, }; +static struct resource ssp_resources[] = { + { + .start = TNETV107X_SSP_BASE, + .end = TNETV107X_SSP_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ssp_device = { + .name = "ti-ssp", + .id = -1, + .num_resources = ARRAY_SIZE(ssp_resources), + .resource = ssp_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i; @@ -367,4 +387,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) keypad_device.dev.platform_data = info->keypad_config; platform_device_register(&keypad_device); } + + if (info->ssp_config) { + ssp_device.dev.platform_data = info->ssp_config; + platform_device_register(&ssp_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 5a681d8..c1df563 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -38,12 +38,14 @@ #include #include #include +#include struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ struct matrix_keypad_platform_data *keypad_config; + struct ti_ssp_data *ssp_config; }; extern struct platform_device tnetv107x_wdt_device; diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index daeae06..fcf30e7 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -277,7 +277,7 @@ static struct clk_lookup clks[] = { CLK(NULL, "timer1", &clk_timer1), CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm), CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp), - CLK("ti-ssp.0", NULL, &clk_ssp), + CLK("ti-ssp", NULL, &clk_ssp), CLK(NULL, "clk_tdm0", &clk_tdm0), CLK(NULL, "clk_vlynq", &clk_vlynq), CLK(NULL, "clk_mcdma", &clk_mcdma), -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:05 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:05 -0400 Subject: [PATCH v3 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-5-git-send-email-cyril@ti.com> This patch adds an SPI master implementation that operates on top of an underlying TI-SSP port. Acked-by: Grant Likely Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 5 + drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 397 +++++++++++++++++++++++++++ 4 files changed, 410 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi_ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 51afc42..63c88fe 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -34,6 +34,11 @@ struct ti_ssp_data { struct ti_ssp_dev_data dev_data[2]; }; +struct ti_ssp_spi_data { + int num_cs; + void (*select)(int cs); +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 91c2f4f..4d282a0 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -298,6 +298,13 @@ config SPI_STMP3XXX help SPI driver for Freescale STMP37xx/378x SoC SSP interface +config SPI_TI_SSP + tristate "TI SSP Controller SPI Driver" + depends on TI_SSP + help + This selects an SPI master implementation using a TI sequencer + serial port. + config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e9cbd18..a427f3c 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c new file mode 100644 index 0000000..a566158 --- /dev/null +++ b/drivers/spi/spi_ti_ssp.c @@ -0,0 +1,397 @@ +/* + * Sequencer Serial Port (SSP) based SPI master driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) + +struct ti_ssp_spi { + const struct ti_ssp_spi_data *pdata; + struct spi_master *master; + struct device *dev; + spinlock_t lock; + struct list_head msg_queue; + struct completion complete; + int shutdown:1; + struct workqueue_struct *workqueue; + struct work_struct work; + u8 mode, bpw; + int cs_active; + u32 pc_en, pc_dis, pc_wr, pc_rd; +}; + +static u32 do_read_data(struct ti_ssp_spi *hw) +{ + u32 ret; + + ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); + return ret; +} + +static void do_write_data(struct ti_ssp_spi *hw, u32 data) +{ + ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); +} + +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, + struct spi_transfer *t) +{ + int count; + + if (hw->bpw <= 8) { + u8 *rx = t->rx_buf; + const u8 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 1) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else if (hw->bpw <= 16) { + u16 *rx = t->rx_buf; + const u16 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 2) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else { + u32 *rx = t->rx_buf; + const u32 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 4) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } + + msg->actual_length += count; /* bytes transferred */ + + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, + hw->bpw, count, (count < t->len) ? " (under)" : ""); + + return (count < t->len) ? -EIO : 0; /* left over data */ +} + +static void chip_select(struct ti_ssp_spi *hw, int cs_active) +{ + cs_active = !!cs_active; + if (cs_active == hw->cs_active) + return; + ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); + hw->cs_active = cs_active; +} + +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) + +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) +{ + int error, idx = 0; + u32 seqram[16]; + u32 cs_en, cs_dis, clk; + u32 topbits, botbits; + + mode &= MODE_BITS; + if (mode == hw->mode && bpw == hw->bpw) + return 0; + + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; + + /* Construct instructions */ + + /* Disable Chip Select */ + hw->pc_dis = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; + + /* Enable Chip Select */ + hw->pc_en = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Reads and writes need to be split for bpw > 16 */ + topbits = (bpw > 16) ? 16 : bpw; + botbits = bpw - topbits; + + /* Write */ + hw->pc_wr = idx; + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; + if (botbits) + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Read */ + hw->pc_rd = idx; + if (botbits) + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + error = ti_ssp_load(hw->dev, 0, seqram, idx); + if (error < 0) + return error; + + error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? + 0 : SSP_EARLY_DIN)); + if (error < 0) + return error; + + hw->bpw = bpw; + hw->mode = mode; + + return error; +} + +static void ti_ssp_spi_work(struct work_struct *work) +{ + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); + + spin_lock_irq(&hw->lock); + + while (!list_empty(&hw->msg_queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + int status = 0; + + m = container_of(hw->msg_queue.next, struct spi_message, + queue); + + list_del_init(&m->queue); + + spi = m->spi; + + if (hw->pdata->select) + hw->pdata->select(spi->chip_select); + + list_for_each_entry(t, &m->transfers, transfer_list) { + int bpw = spi->bits_per_word; + int xfer_status; + + if (t->bits_per_word) + bpw = t->bits_per_word; + + if (setup_xfer(hw, bpw, spi->mode) < 0) + break; + + chip_select(hw, 1); + + spin_unlock_irq(&hw->lock); + + xfer_status = do_transfer(hw, m, t); + if (xfer_status < 0) + status = xfer_status; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + spin_lock_irq(&hw->lock); + + if (t->cs_change) + chip_select(hw, 0); + } + + chip_select(hw, 0); + m->status = status; + m->complete(m->context); + } + + if (hw->shutdown) + complete(&hw->complete); + + spin_unlock_irq(&hw->lock); +} + +static int ti_ssp_spi_setup(struct spi_device *spi) +{ + if (spi->bits_per_word > 32) + return -EINVAL; + + return 0; +} + +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) +{ + struct ti_ssp_spi *hw; + struct spi_transfer *t; + unsigned long flags; + int error = 0; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + hw = spi_master_get_devdata(spi->master); + + if (list_empty(&m->transfers) || !m->complete) + return -EINVAL; + + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->len && !(t->rx_buf || t->tx_buf)) { + dev_err(&spi->dev, "invalid xfer, no buffer\n"); + return -EINVAL; + } + + if (t->len && t->rx_buf && t->tx_buf) { + dev_err(&spi->dev, "invalid xfer, full duplex\n"); + return -EINVAL; + } + + if (t->bits_per_word > 32) { + dev_err(&spi->dev, "invalid xfer width %d\n", + t->bits_per_word); + return -EINVAL; + } + } + + spin_lock_irqsave(&hw->lock, flags); + if (hw->shutdown) { + error = -ESHUTDOWN; + goto error_unlock; + } + list_add_tail(&m->queue, &hw->msg_queue); + queue_work(hw->workqueue, &hw->work); +error_unlock: + spin_unlock_irqrestore(&hw->lock, flags); + return error; +} + +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) +{ + const struct ti_ssp_spi_data *pdata; + struct ti_ssp_spi *hw; + struct spi_master *master; + struct device *dev = &pdev->dev; + int error = 0; + + pdata = dev->platform_data; + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); + if (!master) { + dev_err(dev, "cannot allocate SPI master\n"); + return -ENOMEM; + } + + hw = spi_master_get_devdata(master); + platform_set_drvdata(pdev, hw); + + hw->master = master; + hw->dev = dev; + hw->pdata = pdata; + + spin_lock_init(&hw->lock); + init_completion(&hw->complete); + INIT_LIST_HEAD(&hw->msg_queue); + INIT_WORK(&hw->work, ti_ssp_spi_work); + + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); + if (!hw->workqueue) { + error = -ENOMEM; + dev_err(dev, "work queue creation failed\n"); + goto error_wq; + } + + master->bus_num = pdev->id; + master->num_chipselect = hw->pdata->num_cs; + master->mode_bits = MODE_BITS; + master->flags = SPI_MASTER_HALF_DUPLEX; + master->setup = ti_ssp_spi_setup; + master->transfer = ti_ssp_spi_transfer; + + error = spi_register_master(master); + if (error) { + dev_err(dev, "master registration failed\n"); + goto error_reg; + } + + return 0; + +error_reg: + destroy_workqueue(hw->workqueue); +error_wq: + spi_master_put(master); + return error; +} + +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) +{ + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); + int error; + + hw->shutdown = 1; + while (!list_empty(&hw->msg_queue)) { + error = wait_for_completion_interruptible(&hw->complete); + if (error < 0) { + hw->shutdown = 0; + return error; + } + } + destroy_workqueue(hw->workqueue); + spi_unregister_master(hw->master); + + return 0; +} + +static struct platform_driver ti_ssp_spi_driver = { + .probe = ti_ssp_spi_probe, + .remove = __devexit_p(ti_ssp_spi_remove), + .driver = { + .name = "ti-ssp-spi", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_spi_init(void) +{ + return platform_driver_register(&ti_ssp_spi_driver); +} +subsys_initcall(ti_ssp_spi_init); + +static void __exit ti_ssp_spi_exit(void) +{ + platform_driver_unregister(&ti_ssp_spi_driver); +} +module_exit(ti_ssp_spi_exit); + +MODULE_DESCRIPTION("SSP SPI Master"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spi_ti_ssp"); -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:06 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:06 -0400 Subject: [PATCH v3 05/12] davinci: add spi devices on tnetv107x evm In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-6-git-send-email-cyril@ti.com> This patch adds definitions for spi devices on the tnetv107x evm platform. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 45 +++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 401ad26..c37c5c6 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 +#define EVM_SPI_CS_GPIO 54 static int initialize_gpio(int gpio, char *desc) { @@ -203,9 +205,47 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static void spi_select_device(int cs) +{ + static int gpio; + + if (!gpio) { + int ret; + ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel"); + if (ret < 0) { + pr_err("cannot open spi chipsel gpio\n"); + gpio = -ENOSYS; + return; + } else { + gpio = EVM_SPI_CS_GPIO; + gpio_direction_output(gpio, 0); + } + } + + if (gpio < 0) + return; + + return gpio_set_value(gpio, cs ? 1 : 0); +} + +static const struct ti_ssp_spi_data spi_master_data = { + .num_cs = 2, + .select = spi_select_device, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [1] = { + .dev_name = "ti-ssp-spi", + .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | + SSP_PIN_SEL(1, SSP_DATA) | + SSP_PIN_SEL(2, SSP_CHIPSEL) | + SSP_PIN_SEL(3, SSP_IN) | + SSP_INPUT_SEL(3), + .pdata = &spi_master_data, + .pdata_sz = sizeof(spi_master_data), + }, }, }; @@ -217,6 +257,9 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct spi_board_info spi_info[] __initconst = { +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -224,6 +267,8 @@ static __init void tnetv107x_evm_board_init(void) davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); + + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:08 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:08 -0400 Subject: [PATCH v3 07/12] davinci: add tnetv107x evm regulators In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-8-git-send-email-cyril@ti.com> This patch adds regulator and spi board info definitions for the tps6524x power management IC found on tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 85 +++++++++++++++++++++++++++ 1 files changed, 85 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index c37c5c6..d4c3d18 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -257,7 +260,89 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct regulator_consumer_supply usb_consumers[] = { + REGULATOR_SUPPLY("vbus", "musb_hdrc.1"), +}; + +static struct regulator_consumer_supply lcd_consumers[] = { + REGULATOR_SUPPLY("vlcd", "tps6116x"), +}; + +static struct regulator_init_data regulators[] = { + { + .constraints = { + .name = "DCDC1", + .min_uV = 1000000, + .max_uV = 1000000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC2", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC3", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 4800000, + .max_uV = 4800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(usb_consumers), + .consumer_supplies = usb_consumers, + .constraints = { + .name = "USB", + .min_uA = 200000, + .max_uA = 1000000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | + REGULATOR_CHANGE_STATUS, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(lcd_consumers), + .consumer_supplies = lcd_consumers, + .constraints = { + .name = "LCD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, +}; + static struct spi_board_info spi_info[] __initconst = { + { + .modalias = "tps6524x", + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + .platform_data = regulators, + }, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:07 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:07 -0400 Subject: [PATCH v3 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-7-git-send-email-cyril@ti.com> TPS6524X provides three step-down converters and two general-purpose LDO voltage regulators. This device is interfaced using SPI. Acked-by: Mark Brown Signed-off-by: Cyril Chemparathy --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++++++++++ 3 files changed, 703 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/tps6524x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 172951b..7875c2e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -235,5 +235,15 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. +config REGULATOR_TPS6524X + tristate "TI TPS6524X Power regulators" + depends on TI_SSP + help + This driver supports TPS6524X voltage regulator chips. TPS6524X + provides three step-down converters and two general-purpose LDO + voltage regulators. This device is interfaced using a customized + serial interface currently supported on the sequencer serial + port controller. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 8285fd8..a8e5bc0 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c new file mode 100644 index 0000000..6d6cc5e --- /dev/null +++ b/drivers/regulator/tps6524x-regulator.c @@ -0,0 +1,692 @@ +/* + * Regulator driver for TPS6524x PMIC + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_LDO_SET 0x0 +#define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */ +#define LDO_VSEL_MASK 0x0f +#define LDO2_ILIM_SHIFT 12 +#define LDO2_VSEL_SHIFT 4 +#define LDO1_ILIM_SHIFT 8 +#define LDO1_VSEL_SHIFT 0 + +#define REG_BLOCK_EN 0x1 +#define BLOCK_MASK 1 +#define BLOCK_LDO1_SHIFT 0 +#define BLOCK_LDO2_SHIFT 1 +#define BLOCK_LCD_SHIFT 2 +#define BLOCK_USB_SHIFT 3 + +#define REG_DCDC_SET 0x2 +#define DCDC_VDCDC_MASK 0x1f +#define DCDC_VDCDC1_SHIFT 0 +#define DCDC_VDCDC2_SHIFT 5 +#define DCDC_VDCDC3_SHIFT 10 + +#define REG_DCDC_EN 0x3 +#define DCDCDCDC_EN_MASK 0x1 +#define DCDCDCDC1_EN_SHIFT 0 +#define DCDCDCDC1_PG_MSK BIT(1) +#define DCDCDCDC2_EN_SHIFT 2 +#define DCDCDCDC2_PG_MSK BIT(3) +#define DCDCDCDC3_EN_SHIFT 4 +#define DCDCDCDC3_PG_MSK BIT(5) + +#define REG_USB 0x4 +#define USB_ILIM_SHIFT 0 +#define USB_ILIM_MASK 0x3 +#define USB_TSD_SHIFT 2 +#define USB_TSD_MASK 0x3 +#define USB_TWARN_SHIFT 4 +#define USB_TWARN_MASK 0x3 +#define USB_IWARN_SD BIT(6) +#define USB_FAST_LOOP BIT(7) + +#define REG_ALARM 0x5 +#define ALARM_LDO1 BIT(0) +#define ALARM_DCDC1 BIT(1) +#define ALARM_DCDC2 BIT(2) +#define ALARM_DCDC3 BIT(3) +#define ALARM_LDO2 BIT(4) +#define ALARM_USB_WARN BIT(5) +#define ALARM_USB_ALARM BIT(6) +#define ALARM_LCD BIT(9) +#define ALARM_TEMP_WARM BIT(10) +#define ALARM_TEMP_HOT BIT(11) +#define ALARM_NRST BIT(14) +#define ALARM_POWERUP BIT(15) + +#define REG_INT_ENABLE 0x6 +#define INT_LDO1 BIT(0) +#define INT_DCDC1 BIT(1) +#define INT_DCDC2 BIT(2) +#define INT_DCDC3 BIT(3) +#define INT_LDO2 BIT(4) +#define INT_USB_WARN BIT(5) +#define INT_USB_ALARM BIT(6) +#define INT_LCD BIT(9) +#define INT_TEMP_WARM BIT(10) +#define INT_TEMP_HOT BIT(11) +#define INT_GLOBAL_EN BIT(15) + +#define REG_INT_STATUS 0x7 +#define STATUS_LDO1 BIT(0) +#define STATUS_DCDC1 BIT(1) +#define STATUS_DCDC2 BIT(2) +#define STATUS_DCDC3 BIT(3) +#define STATUS_LDO2 BIT(4) +#define STATUS_USB_WARN BIT(5) +#define STATUS_USB_ALARM BIT(6) +#define STATUS_LCD BIT(9) +#define STATUS_TEMP_WARM BIT(10) +#define STATUS_TEMP_HOT BIT(11) + +#define REG_SOFTWARE_RESET 0xb +#define REG_WRITE_ENABLE 0xd +#define REG_REV_ID 0xf + +#define N_DCDC 3 +#define N_LDO 2 +#define N_SWITCH 2 +#define N_REGULATORS (3 /* DCDC */ + \ + 2 /* LDO */ + \ + 2 /* switch */) + +#define FIXED_ILIMSEL BIT(0) +#define FIXED_VOLTAGE BIT(1) + +#define CMD_READ(reg) ((reg) << 6) +#define CMD_WRITE(reg) (BIT(5) | (reg) << 6) +#define STAT_CLK BIT(3) +#define STAT_WRITE BIT(2) +#define STAT_INVALID BIT(1) +#define STAT_WP BIT(0) + +struct field { + int reg; + int shift; + int mask; +}; + +struct supply_info { + const char *name; + int n_voltages; + const int *voltages; + int fixed_voltage; + int n_ilimsels; + const int *ilimsels; + int fixed_ilimsel; + int flags; + struct field enable, voltage, ilimsel; +}; + +struct tps6524x { + struct device *dev; + struct spi_device *spi; + struct mutex lock; + struct regulator_desc desc[N_REGULATORS]; + struct regulator_dev *rdev[N_REGULATORS]; +}; + +static int __read_reg(struct tps6524x *hw, int reg) +{ + int error = 0; + u16 cmd = CMD_READ(reg), in; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = ∈ + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "read reg %d, data %x, status %x\n", + reg, in, status); + + if (!(status & STAT_CLK) || (status & STAT_WRITE)) + return -EIO; + + if (status & STAT_INVALID) + return -EINVAL; + + return in; +} + +static int read_reg(struct tps6524x *hw, int reg) +{ + int ret; + + mutex_lock(&hw->lock); + ret = __read_reg(hw, reg); + mutex_unlock(&hw->lock); + + return ret; +} + +static int __write_reg(struct tps6524x *hw, int reg, int val) +{ + int error = 0; + u16 cmd = CMD_WRITE(reg), out = val; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = &out; + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n", + reg, out, status); + + if (!(status & STAT_CLK) || !(status & STAT_WRITE)) + return -EIO; + + if (status & (STAT_INVALID | STAT_WP)) + return -EINVAL; + + return error; +} + +static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + ret = __read_reg(hw, reg); + if (ret < 0) + return ret; + + ret &= ~mask; + ret |= val; + + ret = __write_reg(hw, reg, ret); + + return (ret < 0) ? ret : 0; +} + +static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + mutex_lock(&hw->lock); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 1); + if (ret) { + dev_err(hw->dev, "failed to set write enable\n"); + goto error; + } + + ret = __rmw_reg(hw, reg, mask, val); + if (ret) + dev_err(hw->dev, "failed to rmw register %d\n", reg); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 0); + if (ret) { + dev_err(hw->dev, "failed to clear write enable\n"); + goto error; + } + +error: + mutex_unlock(&hw->lock); + + return ret; +} + +static int read_field(struct tps6524x *hw, const struct field *field) +{ + int tmp; + + tmp = read_reg(hw, field->reg); + if (tmp < 0) + return tmp; + + return (tmp >> field->shift) & field->mask; +} + +static int write_field(struct tps6524x *hw, const struct field *field, + int val) +{ + if (val & ~field->mask) + return -EOVERFLOW; + + return rmw_protect(hw, field->reg, + field->mask << field->shift, + val << field->shift); +} + +static const int dcdc1_voltages[] = { + 800000, 825000, 850000, 875000, + 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, + 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, + 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, + 1500000, 1525000, 1550000, 1575000, +}; + +static const int dcdc2_voltages[] = { + 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, + 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, + 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, + 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, +}; + +static const int dcdc3_voltages[] = { + 2400000, 2450000, 2500000, 2550000, 2600000, + 2650000, 2700000, 2750000, 2800000, 2850000, + 2900000, 2950000, 3000000, 3050000, 3100000, + 3150000, 3200000, 3250000, 3300000, 3350000, + 3400000, 3450000, 3500000, 3550000, 3600000, +}; + +static const int ldo1_voltages[] = { + 4300000, 4350000, 4400000, 4450000, + 4500000, 4550000, 4600000, 4650000, + 4700000, 4750000, 4800000, 4850000, + 4900000, 4950000, 5000000, 5050000, +}; + +static const int ldo2_voltages[] = { + 1100000, 1150000, 1200000, 1250000, + 1300000, 1700000, 1750000, 1800000, + 1850000, 1900000, 3150000, 3200000, + 3250000, 3300000, 3350000, 3400000, +}; + +static const int ldo_ilimsel[] = { + 400000, 1500000 +}; + +static const int usb_ilimsel[] = { + 200000, 400000, 800000, 1000000 +}; + +#define __MK_FIELD(_reg, _mask, _shift) \ + { .reg = (_reg), .mask = (_mask), .shift = (_shift), } + +static const struct supply_info supply_info[N_REGULATORS] = { + { + .name = "DCDC1", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc1_voltages), + .voltages = dcdc1_voltages, + .fixed_ilimsel = 2400000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC1_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC1_SHIFT), + }, + { + .name = "DCDC2", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc2_voltages), + .voltages = dcdc2_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC2_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC2_SHIFT), + }, + { + .name = "DCDC3", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc3_voltages), + .voltages = dcdc3_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC3_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC3_SHIFT), + }, + { + .name = "LDO1", + .n_voltages = ARRAY_SIZE(ldo1_voltages), + .voltages = ldo1_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO1_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO1_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO1_ILIM_SHIFT), + }, + { + .name = "LDO2", + .n_voltages = ARRAY_SIZE(ldo2_voltages), + .voltages = ldo2_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO2_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO2_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO2_ILIM_SHIFT), + }, + { + .name = "USB", + .flags = FIXED_VOLTAGE, + .fixed_voltage = 5000000, + .n_ilimsels = ARRAY_SIZE(usb_ilimsel), + .ilimsels = usb_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_USB_SHIFT), + .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK, + USB_ILIM_SHIFT), + }, + { + .name = "LCD", + .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, + .fixed_voltage = 5000000, + .fixed_ilimsel = 400000, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LCD_SHIFT), + }, +}; + +static int list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return selector ? -EINVAL : info->fixed_voltage; + + if (selector < 0 || selector >= info->n_voltages) + return -EINVAL; + + return info->voltages[selector]; +} + +static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return -EINVAL; + + for (i = 0; i < info->n_voltages; i++) + if (min_uV <= info->voltages[i] && + max_uV >= info->voltages[i]) + break; + + if (i >= info->n_voltages) + return -EINVAL; + + return write_field(hw, &info->voltage, i); +} + +static int get_voltage(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return info->fixed_voltage; + + ret = read_field(hw, &info->voltage); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_voltages)) + return -EIO; + + return info->voltages[ret]; +} + +static int set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return -EINVAL; + + for (i = 0; i < info->n_ilimsels; i++) + if (min_uA <= info->ilimsels[i] && + max_uA >= info->ilimsels[i]) + break; + + if (i >= info->n_ilimsels) + return -EINVAL; + + return write_field(hw, &info->ilimsel, i); +} + +static int get_current_limit(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return info->fixed_ilimsel; + + ret = read_field(hw, &info->ilimsel); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_ilimsels)) + return -EIO; + + return info->ilimsels[ret]; +} + +static int enable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 1); +} + +static int disable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 0); +} + +static int is_supply_enabled(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return read_field(hw, &info->enable); +} + +static struct regulator_ops regulator_ops = { + .is_enabled = is_supply_enabled, + .enable = enable_supply, + .disable = disable_supply, + .get_voltage = get_voltage, + .set_voltage = set_voltage, + .list_voltage = list_voltage, + .set_current_limit = set_current_limit, + .get_current_limit = get_current_limit, +}; + +static int __devexit pmic_remove(struct spi_device *spi) +{ + struct tps6524x *hw = spi_get_drvdata(spi); + int i; + + if (!hw) + return 0; + for (i = 0; i < N_REGULATORS; i++) { + if (hw->rdev[i]) + regulator_unregister(hw->rdev[i]); + hw->rdev[i] = NULL; + } + spi_set_drvdata(spi, NULL); + kfree(hw); + return 0; +} + +static int __devinit pmic_probe(struct spi_device *spi) +{ + struct tps6524x *hw; + struct device *dev = &spi->dev; + const struct supply_info *info = supply_info; + struct regulator_init_data *init_data; + int ret = 0, i; + + init_data = dev->platform_data; + if (!init_data) { + dev_err(dev, "could not find regulator platform data\n"); + return -EINVAL; + } + + hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); + if (!hw) { + dev_err(dev, "cannot allocate regulator private data\n"); + return -ENOMEM; + } + spi_set_drvdata(spi, hw); + + memset(hw, 0, sizeof(struct tps6524x)); + hw->dev = dev; + hw->spi = spi_dev_get(spi); + mutex_init(&hw->lock); + + for (i = 0; i < N_REGULATORS; i++, info++, init_data++) { + hw->desc[i].name = info->name; + hw->desc[i].id = i; + hw->desc[i].n_voltages = info->n_voltages; + hw->desc[i].ops = ®ulator_ops; + hw->desc[i].type = REGULATOR_VOLTAGE; + hw->desc[i].owner = THIS_MODULE; + + if (info->flags & FIXED_VOLTAGE) + hw->desc[i].n_voltages = 1; + + hw->rdev[i] = regulator_register(&hw->desc[i], dev, + init_data, hw); + if (IS_ERR(hw->rdev[i])) { + ret = PTR_ERR(hw->rdev[i]); + hw->rdev[i] = NULL; + goto fail; + } + } + + return 0; + +fail: + pmic_remove(spi); + return ret; +} + +static struct spi_driver pmic_driver = { + .probe = pmic_probe, + .remove = __devexit_p(pmic_remove), + .driver = { + .name = "tps6524x", + .owner = THIS_MODULE, + }, +}; + +static int __init pmic_driver_init(void) +{ + return spi_register_driver(&pmic_driver); +} +subsys_initcall_sync(pmic_driver_init); + +static void __exit pmic_driver_exit(void) +{ + spi_unregister_driver(&pmic_driver); +} +module_exit(pmic_driver_exit); + +MODULE_DESCRIPTION("TPS6524X PMIC Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:tps6524x"); -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:09 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:09 -0400 Subject: [PATCH v3 08/12] gpio: add ti-ssp virtual gpio driver In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-9-git-send-email-cyril@ti.com> This patch adds a GPIO driver based on TI's SSP device. This driver does not support GPIO-IRQs. Acked-by: Grant Likely Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 4 + drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/ti-ssp-gpio.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index 63c88fe..21f1429 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -39,6 +39,10 @@ struct ti_ssp_spi_data { void (*select)(int cs); }; +struct ti_ssp_gpio_data { + int start; +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..e400761 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -111,6 +111,16 @@ config GPIO_SCH This driver can also be built as a module. If so, the module will be called sch-gpio. +config GPIO_TI_SSP + tristate "TI SSP Controller GPIO Driver" + depends on GPIOLIB && TI_SSP + help + Say yes here to support a virtual GPIO interface on TI SSP ports. + Each SSP port translates into 4 GPIOs, with no IRQ support. + + This driver can also be built as a module. If so, the module + will be called ti-ssp-gpio. + comment "I2C GPIO expanders:" config GPIO_MAX7300 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..98b4551 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c new file mode 100644 index 0000000..c046713 --- /dev/null +++ b/drivers/gpio/ti-ssp-gpio.c @@ -0,0 +1,200 @@ +/* + * Sequencer Serial Port (SSP) based virtual GPIO driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ti_ssp_gpio { + struct gpio_chip chip; +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) + struct device *dev; + spinlock_t lock; + u8 out; + u32 iosel; +}; + +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error = 0; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + spin_unlock(&gpio->lock); + + return error; +} + +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + if (error < 0) + goto error; + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + error = ti_ssp_raw_write(gpio->dev, gpio->out); + +error: + spin_unlock(&gpio->lock); + return error; +} + +static int value_get(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int ret; + + spin_lock(&gpio->lock); + + ret = ti_ssp_raw_read(gpio->dev); + if (ret >= 0) + ret = (ret & BIT(gpio_num)) ? 1 : 0; + + spin_unlock(&gpio->lock); + return ret; +} + +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + + spin_lock(&gpio->lock); + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + ti_ssp_raw_write(gpio->dev, gpio->out); + + spin_unlock(&gpio->lock); +} + +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) +{ + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct ti_ssp_gpio *gpio; + int error; + + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(dev, "cannot allocate driver data\n"); + return -ENOMEM; + } + + gpio->dev = dev; + gpio->iosel = SSP_PIN_SEL(0, SSP_IN) | SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | SSP_PIN_SEL(3, SSP_IN); + spin_lock_init(&gpio->lock); + platform_set_drvdata(pdev, gpio); + + gpio->chip.base = pdata->start; + gpio->chip.ngpio = 4; + gpio->chip.dev = &pdev->dev; + gpio->chip.label = "ti_ssp_gpio"; + gpio->chip.owner = THIS_MODULE; + gpio->chip.get = value_get; + gpio->chip.set = value_set; + gpio->chip.direction_input = direction_in; + gpio->chip.direction_output = direction_out; + + error = gpiochip_add(&gpio->chip); + if (error < 0) { + dev_err(dev, "gpio chip registration failed (%d)\n", error); + goto error; + } + + dev_info(dev, "ssp gpio interface registered\n"); + return 0; + +error: + kfree(gpio); + return error; +} + +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) +{ + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); + int error; + + error = gpiochip_remove(&gpio->chip); + if (error < 0) + return error; + kfree(gpio); + return 0; +} + +static struct platform_driver ti_ssp_gpio_driver = { + .probe = ti_ssp_gpio_probe, + .remove = __devexit_p(ti_ssp_gpio_remove), + .driver = { + .name = "ti-ssp-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_gpio_init(void) +{ + return platform_driver_register(&ti_ssp_gpio_driver); +} +subsys_initcall(ti_ssp_gpio_init); + +static void __exit ti_ssp_gpio_exit(void) +{ + platform_driver_unregister(&ti_ssp_gpio_driver); +} +module_exit(ti_ssp_gpio_exit); + +MODULE_DESCRIPTION("GPIO interface for TI-SSP"); +MODULE_AUTHOR("Cyril Chemparathy "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti-ssp-gpio"); -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:10 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:10 -0400 Subject: [PATCH v3 09/12] davinci: add tnetv107x evm ti-ssp gpio device In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-10-git-send-email-cyril@ti.com> This patch adds definitions to hook up one of the ti-ssp ports to the SSP GPIO driver. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index d4c3d18..270ba26 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -40,6 +40,8 @@ #include #include +#define SSP_GPIO_START 128 + #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 @@ -236,9 +238,22 @@ static const struct ti_ssp_spi_data spi_master_data = { .select = spi_select_device, }; +static const struct ti_ssp_gpio_data ssp_gpio_data = { + .start = SSP_GPIO_START, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [0] = { + .dev_name = "ti-ssp-gpio", + .iosel = SSP_PIN_SEL(0, SSP_IN) | + SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | + SSP_PIN_SEL(3, SSP_IN), + .pdata = &ssp_gpio_data, + .pdata_sz = sizeof(ssp_gpio_data), + }, [1] = { .dev_name = "ti-ssp-spi", .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:11 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:11 -0400 Subject: [PATCH v3 10/12] backlight: add support for tps6116x controller In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-11-git-send-email-cyril@ti.com> TPS6116x is an EasyScale backlight controller device. This driver supports TPS6116x devices connected on a single GPIO. Signed-off-by: Cyril Chemparathy --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+), 1 deletions(-) create mode 100644 drivers/video/backlight/tps6116x.c diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index e54a337..06e868e 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -307,6 +307,13 @@ config BACKLIGHT_PCF50633 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to enable its driver. +config BACKLIGHT_TPS6116X + tristate "TPS6116X LCD Backlight" + depends on GENERIC_GPIO + help + This driver controls the LCD backlight level for EasyScale capable + SSP connected backlight controllers. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 44c0f81..5d407c8 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -35,4 +35,4 @@ obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o - +obj-$(CONFIG_BACKLIGHT_TPS6116X)+= tps6116x.o diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c new file mode 100644 index 0000000..7a9f8ca --- /dev/null +++ b/drivers/video/backlight/tps6116x.c @@ -0,0 +1,340 @@ +/* + * TPS6116X LCD Backlight Controller Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS6116X_MAX_INTENSITY 31 +#define TPS6116X_DEFAULT_INTENSITY 10 + +/* Easyscale timing w/ margin (usecs) */ +#define T_POWER_SETTLE 2000 +#define T_ES_DELAY 120 +#define T_ES_DETECT 280 +#define T_ES_WINDOW (1000 - T_ES_DELAY - T_ES_DETECT) +#define T_START 3 +#define T_EOS 3 +#define T_INACTIVE 3 +#define T_ACTIVE (3 * T_INACTIVE) + +#define CMD_SET 0x72 + +struct tps6116x { + struct ti_ssp_device *handle; + struct device *dev; + int gpio, gpio_initialized; + struct mutex lock; + int intensity; + int power; + struct backlight_properties props; + struct backlight_device *bl; + int suspended:1; + struct regulator *regulator; +}; + +static int __set_power(struct tps6116x *hw, int power) +{ + unsigned long flags; + int error; + + power = !!power; + if (power == hw->power) + return 0; /* nothing to do */ + + /* disabling is simple... choke power */ + if (!power) { + error = regulator_disable(hw->regulator); + goto done; + } + + /* set ctrl pin init state for easyscale detection */ + gpio_set_value(hw->gpio, 0); + + error = regulator_enable(hw->regulator); + if (error < 0) + goto done; + + udelay(T_POWER_SETTLE); + + /* + * Now that the controller is powered up, we need to put it into 1-wire + * mode. This is a timing sensitive operation, hence the irq disable. + * Ideally, this should happen rarely, and mostly at init, so disabling + * interrupts for the duration should not be a problem. + */ + local_irq_save(flags); + + gpio_set_value(hw->gpio, 1); + udelay(T_ES_DELAY); + gpio_set_value(hw->gpio, 0); + udelay(T_ES_DETECT); + gpio_set_value(hw->gpio, 1); + + local_irq_restore(flags); + +done: + if (error >= 0) + hw->power = power; + + return error; +} + +static void __write_byte(struct tps6116x *hw, u8 data) +{ + int bit; + + gpio_set_value(hw->gpio, 1); + udelay(T_START); + + for (bit = 0; bit < 8; bit++, data <<= 1) { + int val = data & 0x80; + int t_lo = val ? T_INACTIVE : T_ACTIVE; + int t_hi = val ? T_ACTIVE : T_INACTIVE; + + gpio_set_value(hw->gpio, 0); + udelay(t_lo); + gpio_set_value(hw->gpio, 1); + udelay(t_hi); + } + + gpio_set_value(hw->gpio, 0); + udelay(T_EOS); + gpio_set_value(hw->gpio, 1); +} + +static void __set_intensity(struct tps6116x *hw, int intensity) +{ + unsigned long flags; + + intensity = clamp(intensity, 0, TPS6116X_MAX_INTENSITY); + + local_irq_save(flags); + __write_byte(hw, CMD_SET); + __write_byte(hw, intensity); + local_irq_restore(flags); +} + +static int set_intensity(struct tps6116x *hw, int intensity) +{ + int error = 0; + + if (intensity == hw->intensity) + return 0; + + mutex_lock(&hw->lock); + + if (!hw->gpio_initialized) { + error = gpio_request_one(hw->gpio, GPIOF_DIR_OUT, + dev_name(hw->dev)); + if (error < 0) + goto error; + hw->gpio_initialized = 1; + } + + error = __set_power(hw, intensity ? 1 : 0); + if (error < 0) + goto error; + + if (intensity > 0) + __set_intensity(hw, intensity); + + hw->intensity = intensity; +error: + mutex_unlock(&hw->lock); + + return error; +} + +static ssize_t intensity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "%d\n", hw->intensity); + + return len; +} + +static ssize_t intensity_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + unsigned long intensity; + int error; + + error = strict_strtoul(buf, 10, &intensity); + if (error < 0) + return error; + + error = set_intensity(hw, intensity); + if (error < 0) + return error; + + return count; +} + +DEVICE_ATTR(intensity, S_IWUSR | S_IRUGO, intensity_show, intensity_store); + +static int get_brightness(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + + return hw->intensity; +} + +static int update_status(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + int intensity = bl->props.brightness; + + if (hw->suspended) + intensity = 0; + if (bl->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + return set_intensity(hw, intensity); +} + +static const struct backlight_ops tps6116x_backlight_ops = { + .get_brightness = get_brightness, + .update_status = update_status, +}; + +static int __devinit tps6116x_probe(struct platform_device *pdev) +{ + struct tps6116x *hw; + struct device *dev = &pdev->dev; + struct backlight_properties props; + int error; + + hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL); + if (!hw) { + error = -ENOMEM; + dev_err(dev, "cannot allocate driver data\n"); + goto fail0; + } + platform_set_drvdata(pdev, hw); + + memset(hw, 0, sizeof(struct tps6116x)); + hw->gpio = (int)dev->platform_data; + hw->dev = dev; + + mutex_init(&hw->lock); + + error = device_create_file(dev, &dev_attr_intensity); + if (error < 0) { + dev_err(dev, "cannot create device attributes\n"); + goto fail1; + } + + hw->regulator = regulator_get(dev, "vlcd"); + if (IS_ERR(hw->regulator)) { + error = PTR_ERR(hw->regulator); + dev_err(dev, "cannot claim regulator\n"); + goto fail2; + } + + memset(&props, 0, sizeof(props)); + props.max_brightness = TPS6116X_MAX_INTENSITY; + props.brightness = TPS6116X_DEFAULT_INTENSITY; + + hw->bl = backlight_device_register("tps6116x", hw->dev, hw, + &tps6116x_backlight_ops, &props); + if (IS_ERR(hw->bl)) { + error = PTR_ERR(hw->bl); + dev_err(dev, "backlight registration failed\n"); + goto fail3; + } + + dev_info(dev, "registered backlight controller\n"); + return 0; + +fail3: + regulator_put(hw->regulator); +fail2: + device_remove_file(dev, &dev_attr_intensity); +fail1: + kfree(hw); + platform_set_drvdata(pdev, NULL); +fail0: + return error; +} + +static int __devexit tps6116x_remove(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + + backlight_device_unregister(hw->bl); + regulator_disable(hw->regulator); + regulator_put(hw->regulator); + device_remove_file(hw->dev, &dev_attr_intensity); + kfree(hw); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int tps6116x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 1; + update_status(hw->bl); + return 0; +} + +static int tps6116x_resume(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 0; + update_status(hw->bl); + return 0; +} + +static struct platform_driver tps6116x_driver = { + .probe = tps6116x_probe, + .remove = __devexit_p(tps6116x_remove), + .suspend = tps6116x_suspend, + .resume = tps6116x_resume, + .driver = { + .name = "tps6116x", + .owner = THIS_MODULE, + }, +}; + +static int __init tps6116x_init(void) +{ + return platform_driver_register(&tps6116x_driver); +} +module_init(tps6116x_init); + +static void __exit tps6116x_exit(void) +{ + platform_driver_unregister(&tps6116x_driver); +} +module_exit(tps6116x_exit); + +MODULE_DESCRIPTION("SSP TPS6116X Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tps6116x"); -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:13 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:13 -0400 Subject: [PATCH v3 12/12] davinci: add tnetv107x evm i2c eeprom device In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-13-git-send-email-cyril@ti.com> The tnetv107x evm board has an I2C device connected on one of the SSP ports. This patch adds board definitions for a GPIO based I2C master, as well as definitions for the eeprom device on these boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 30 +++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index ca61f8a..8b94a63 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include @@ -45,6 +48,8 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_I2C_SDA_GPIO (SSP_GPIO_START + 0) +#define EVM_I2C_SCL_GPIO (SSP_GPIO_START + 1) #define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) @@ -367,6 +372,29 @@ static struct platform_device backlight_device = { .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, }; +struct i2c_gpio_platform_data i2c_data = { + .sda_pin = EVM_I2C_SDA_GPIO, + .scl_pin = EVM_I2C_SCL_GPIO, +}; + +static struct platform_device i2c_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &i2c_data, +}; + +static struct at24_platform_data at24_config = { + .byte_len = SZ_16K / 8, + .page_size = 16, +}; + +static struct i2c_board_info i2c_info[] __initconst = { + { + I2C_BOARD_INFO("24c16", 0x50), + .platform_data = &at24_config, + }, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -376,8 +404,10 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); platform_device_register(&backlight_device); + platform_device_register(&i2c_device); spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Thu Oct 21 16:01:12 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 21 Oct 2010 17:01:12 -0400 Subject: [PATCH v3 11/12] davinci: add tnetv107x evm backlight device In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <1287694873-12904-12-git-send-email-cyril@ti.com> The tnetv107x evm board has a backlight device that is connected on one of the SSP ports. This patch adds the board definitions necessary to plug the backlight driver to the GPIO corresponding to this SSP pin. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 270ba26..ca61f8a 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -45,6 +45,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) { @@ -360,6 +361,12 @@ static struct spi_board_info spi_info[] __initconst = { }, }; +static struct platform_device backlight_device = { + .name = "tps6116x", + .id = -1, + .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -368,6 +375,8 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); + platform_device_register(&backlight_device); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } -- 1.7.0.4 From joe at perches.com Thu Oct 21 16:19:22 2010 From: joe at perches.com (Joe Perches) Date: Thu, 21 Oct 2010 14:19:22 -0700 Subject: [PATCH v3 10/12] backlight: add support for tps6116x controller In-Reply-To: <1287694873-12904-11-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <1287694873-12904-11-git-send-email-cyril@ti.com> Message-ID: <1287695962.15567.98.camel@Joe-Laptop> On Thu, 2010-10-21 at 17:01 -0400, Cyril Chemparathy wrote: > diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c just some trivia: > @@ -0,0 +1,340 @@ [] > +struct tps6116x { > + struct ti_ssp_device *handle; > + struct device *dev; > + int gpio, gpio_initialized; > + struct mutex lock; > + int intensity; > + int power; > + struct backlight_properties props; > + struct backlight_device *bl; > + int suspended:1; > + struct regulator *regulator; > +}; Perhaps several of these should be bool. gpio_initialized, power, suspended [] > +static int __devinit tps6116x_probe(struct platform_device *pdev) > +{ > + struct tps6116x *hw; > + struct device *dev = &pdev->dev; > + struct backlight_properties props; > + int error; > + > + hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL); > + if (!hw) { > + error = -ENOMEM; > + dev_err(dev, "cannot allocate driver data\n"); > + goto fail0; > + } > + platform_set_drvdata(pdev, hw); > + > + memset(hw, 0, sizeof(struct tps6116x)); Unnecessary memset. From khilman at deeprootsystems.com Thu Oct 21 17:26:04 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Thu, 21 Oct 2010 15:26:04 -0700 Subject: [PATCH v3 00/12] tnetv107x ssp driver stack In-Reply-To: <1287694873-12904-1-git-send-email-cyril@ti.com> (Cyril Chemparathy's message of "Thu, 21 Oct 2010 17:01:01 -0400") References: <1287694873-12904-1-git-send-email-cyril@ti.com> Message-ID: <87mxq7p4hv.fsf@deeprootsystems.com> Cyril Chemparathy writes: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). Andrew, looking for some advice here... This is a piece of davinci hardware, but introduces drivers in various subsystems. I'm willing to merge this series via the davinci tree after getting acks from the various subsystem maintainers. Is this an OK approach? It seems best to me to merge this all together. We already have acks for the regulator and gpio driver parts, and the backlight driver has a clear owner in MAINTAINERS. However, who should be doing the final review/ack of the drivers/misc and drivers/gpio changes is less clear to me. Any advice appreciated, Thanks, Kevin > arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ > arch/arm/mach-davinci/devices-tnetv107x.c | 25 + > arch/arm/mach-davinci/include/mach/ti_ssp.h | 98 ++++ > arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + > arch/arm/mach-davinci/tnetv107x.c | 2 +- > drivers/gpio/Kconfig | 10 + > drivers/gpio/Makefile | 1 + > drivers/gpio/ti-ssp-gpio.c | 200 +++++++ > drivers/misc/Kconfig | 11 + > drivers/misc/Makefile | 1 + > drivers/misc/ti_ssp.c | 436 +++++++++++++++ > drivers/regulator/Kconfig | 10 + > drivers/regulator/Makefile | 1 + > drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ > drivers/spi/Kconfig | 7 + > drivers/spi/Makefile | 1 + > drivers/spi/spi_ti_ssp.c | 397 ++++++++++++++ > drivers/video/backlight/Kconfig | 7 + > drivers/video/backlight/Makefile | 2 +- > drivers/video/backlight/tps6116x.c | 340 ++++++++++++ From akpm at linux-foundation.org Thu Oct 21 17:59:02 2010 From: akpm at linux-foundation.org (Andrew Morton) Date: Thu, 21 Oct 2010 15:59:02 -0700 Subject: [PATCH v3 00/12] tnetv107x ssp driver stack In-Reply-To: <87mxq7p4hv.fsf@deeprootsystems.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <87mxq7p4hv.fsf@deeprootsystems.com> Message-ID: <20101021155902.b9702f72.akpm@linux-foundation.org> On Thu, 21 Oct 2010 15:26:04 -0700 Kevin Hilman wrote: > Cyril Chemparathy writes: > > > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > > device. It has a built-in programmable execution engine that can be programmed > > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > Andrew, looking for some advice here... > > This is a piece of davinci hardware, but introduces drivers in various > subsystems. I'm willing to merge this series via the davinci tree after > getting acks from the various subsystem maintainers. Is this an OK > approach? It seems best to me to merge this all together. Yes, that's the best approach. Some of the desired acks may not be forthcoming. In which case the best you can do is to review the code yourself, make the maintainer(s) aware of what's going on and just go ahead and merge it. If people are too busy to look at the code then so be it - we can't really permit that problem to permanently block new drivers. > We already have acks for the regulator and gpio driver parts, and the > backlight driver has a clear owner in MAINTAINERS. However, who should > be doing the final review/ack of the drivers/misc and drivers/gpio > changes is less clear to me. > I'll go and have a look at drivers/misc/ti_ssp.c. > > Thanks, > > Kevin > > > arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ > > arch/arm/mach-davinci/devices-tnetv107x.c | 25 + > > arch/arm/mach-davinci/include/mach/ti_ssp.h | 98 ++++ > > arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + > > arch/arm/mach-davinci/tnetv107x.c | 2 +- > > drivers/gpio/Kconfig | 10 + > > drivers/gpio/Makefile | 1 + > > drivers/gpio/ti-ssp-gpio.c | 200 +++++++ > > drivers/misc/Kconfig | 11 + > > drivers/misc/Makefile | 1 + > > drivers/misc/ti_ssp.c | 436 +++++++++++++++ > > drivers/regulator/Kconfig | 10 + > > drivers/regulator/Makefile | 1 + > > drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ > > drivers/spi/Kconfig | 7 + > > drivers/spi/Makefile | 1 + > > drivers/spi/spi_ti_ssp.c | 397 ++++++++++++++ > > drivers/video/backlight/Kconfig | 7 + > > drivers/video/backlight/Makefile | 2 +- > > drivers/video/backlight/tps6116x.c | 340 ++++++++++++ From akpm at linux-foundation.org Thu Oct 21 18:12:24 2010 From: akpm at linux-foundation.org (Andrew Morton) Date: Thu, 21 Oct 2010 16:12:24 -0700 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287694873-12904-2-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <1287694873-12904-2-git-send-email-cyril@ti.com> Message-ID: <20101021161224.b4c0b623.akpm@linux-foundation.org> On Thu, 21 Oct 2010 17:01:02 -0400 Cyril Chemparathy wrote: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > This patch adds a driver for this controller device. The driver does not > expose a user-land interface. Protocol drivers built on top of this layer are > expected to remain in-kernel. > > > ... > > +struct ti_ssp_dev_data { > + const char *dev_name; > + unsigned long iosel; /* see note below */ > + unsigned long config; > + const void *pdata; > + int pdata_sz; I suppose this really should have type size_t. Also a better name is "pdata_size" - we prefer to avoid this random omission of vowels from kernel identifiers. Just spell it out; it makes it easier to remember. > +}; > + > +struct ti_ssp_data { > + unsigned long out_clock; > + struct ti_ssp_dev_data dev_data[2]; > +}; > + > > ... > > +config TI_SSP > + depends on ARCH_DAVINCI_TNETV107X > + tristate "Sequencer Serial Port support" > + default y Was `y' a good choice? > + ---help--- > + Say Y here if you want support for the Sequencer Serial Port > + in a Texas Instruments TNETV107X SoC. > + > + To compile this driver as a module, choose M here: the > + module will be called ti_ssp. > > ... > > +#define dev2ssp(dev) dev_get_drvdata(dev->parent) > +#define dev2port(dev) (to_platform_device(dev)->id) These could be implemented as C funtions. That's superior because of the typechecking. At present dev2ssp() will happily compile and fail at runtime if passed anystructure which has a 'const struct device *parent'. > +/* Register Access Helpers */ > +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) > +{ > + return __raw_readl(ssp->regs + reg); > +} > + > +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) > +{ > + __raw_writel(val, ssp->regs + reg); > +} Why are the __raw functions used here? > +static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) > +{ > + u32 val = ssp_read(ssp, reg); > + val &= ~mask; > + val |= bits; > + ssp_write(ssp, reg, val); > +} Locking? Perhaps this function must be called under ssp->lock? If so, that should be documented here and it appears that not all callsites actually do that correctly. > > ... > > +static int __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) > +{ > + unsigned val; > + > + /* IOSEL1 gets the least significant 16 bits */ > + val = ssp_read(ssp, REG_IOSEL_1); > + val &= 0xffff << (port ? 0 : 16); > + val |= (iosel & 0xffff) << (port ? 16 : 0); > + ssp_write(ssp, REG_IOSEL_1, val); > + > + /* IOSEL2 gets the most significant 16 bits */ > + val = ssp_read(ssp, REG_IOSEL_2); > + val &= 0x0007 << (port ? 0 : 16); > + val |= (iosel & 0x00070000) >> (port ? 0 : 16); > + ssp_write(ssp, REG_IOSEL_2, val); More rmw's which need locking. It should be documented please. Both callers get it right this time. > + return 0; > +} > + > > ... > > +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) > +{ > + struct ti_ssp *ssp = dev2ssp(dev); > + int port = dev2port(dev); > + int count; > + > + if (pc & ~(0x3f)) > + return -EINVAL; > + > + ssp_port_write(ssp, port, PORT_ADDR, input >> 16); > + ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); > + ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); > + > + ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); > + > + for (count = 10000; count; count--) { > + if ((ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY) == 0) > + break; > + udelay(1); > + } > + > + if (output) { > + *(output) = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | > + (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); > + } > + > + if (!count) { > + dev_err(ssp->dev, "timed out waiting for SSP operation\n"); > + return -EIO; > + } There doesn't seem much point in writing to *output if the port_read() timed out? > > ... > That's all fairly minor stuff. It looks Good Enough For Linux to me. From suk2010 at sina.cn Fri Oct 22 07:21:27 2010 From: suk2010 at sina.cn (suk2010 at sina.cn) Date: Fri, 22 Oct 2010 20:21:27 +0800 Subject: I want to get the address to download the package of Davinci-linux-open-source Message-ID: <20101022122127.9F8042F17B8@mail0.webapp.51uc.com> I  interested in davinci,wo I want to get the address of the  package of  Davinci-linux-open-source  to download for study.thank you -------------- next part -------------- An HTML attachment was scrubbed... URL: From cyril at ti.com Fri Oct 22 07:39:33 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Fri, 22 Oct 2010 08:39:33 -0400 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <20101021161224.b4c0b623.akpm@linux-foundation.org> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <1287694873-12904-2-git-send-email-cyril@ti.com> <20101021161224.b4c0b623.akpm@linux-foundation.org> Message-ID: <4CC18605.80007@ti.com> On 10/21/2010 07:12 PM, Andrew Morton wrote: > > ... > >> +/* Register Access Helpers */ >> +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) >> +{ >> + return __raw_readl(ssp->regs + reg); >> +} >> + >> +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) >> +{ >> + __raw_writel(val, ssp->regs + reg); >> +} > > Why are the __raw functions used here? > These registers are to be accessed native endian at all times, and therefore the le32 conversion done otherwise is inappropriate. Thanks for the feedback. I will post an updated series with these changes. Regards Cyril. From arnd at arndb.de Fri Oct 22 07:48:17 2010 From: arnd at arndb.de (Arnd Bergmann) Date: Fri, 22 Oct 2010 14:48:17 +0200 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <4CC18605.80007@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <20101021161224.b4c0b623.akpm@linux-foundation.org> <4CC18605.80007@ti.com> Message-ID: <201010221448.17728.arnd@arndb.de> On Friday 22 October 2010 14:39:33 Cyril Chemparathy wrote: > >> +/* Register Access Helpers */ > >> +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) > >> +{ > >> + return __raw_readl(ssp->regs + reg); > >> +} > >> + > >> +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) > >> +{ > >> + __raw_writel(val, ssp->regs + reg); > >> +} > > > > Why are the __raw functions used here? > > > > These registers are to be accessed native endian at all times, and > therefore the le32 conversion done otherwise is inappropriate. Won't that break on out-of-order CPUs that need the extra synchronization done in readl/writel? Arnd From alan at lxorguk.ukuu.org.uk Fri Oct 22 09:20:24 2010 From: alan at lxorguk.ukuu.org.uk (Alan Cox) Date: Fri, 22 Oct 2010 15:20:24 +0100 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <1287694873-12904-2-git-send-email-cyril@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <1287694873-12904-2-git-send-email-cyril@ti.com> Message-ID: <20101022152024.65e8f181@lxorguk.ukuu.org.uk> On Thu, 21 Oct 2010 17:01:02 -0400 Cyril Chemparathy wrote: > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > This patch adds a driver for this controller device. The driver does not > expose a user-land interface. Protocol drivers built on top of this layer are > expected to remain in-kernel. I suspect the driver belongs with the mfd drivers not with drivers/misc ? otherwise it looks very nice. From cyril at ti.com Fri Oct 22 14:03:38 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Fri, 22 Oct 2010 15:03:38 -0400 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <20101022152024.65e8f181@lxorguk.ukuu.org.uk> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <1287694873-12904-2-git-send-email-cyril@ti.com> <20101022152024.65e8f181@lxorguk.ukuu.org.uk> Message-ID: <4CC1E00A.3010109@ti.com> On 10/22/2010 10:20 AM, Alan Cox wrote: > On Thu, 21 Oct 2010 17:01:02 -0400 > Cyril Chemparathy wrote: > >> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port >> device. It has a built-in programmable execution engine that can be programmed >> to operate as almost any serial bus (I2C, SPI, EasyScale, and others). >> >> This patch adds a driver for this controller device. The driver does not >> expose a user-land interface. Protocol drivers built on top of this layer are >> expected to remain in-kernel. > > I suspect the driver belongs with the mfd drivers not with drivers/misc ? > > otherwise it looks very nice. Unlike MFDs, this device doesn't have cells with differing functionality. Instead it has functionally identical ports that can operate in a variety of modes. That said, does this still fit in with other MFD drivers? If so, I don't see a problem with moving it there. Thanks Cyril. From cyril at ti.com Fri Oct 22 14:33:43 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Fri, 22 Oct 2010 15:33:43 -0400 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <201010221448.17728.arnd@arndb.de> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <20101021161224.b4c0b623.akpm@linux-foundation.org> <4CC18605.80007@ti.com> <201010221448.17728.arnd@arndb.de> Message-ID: <4CC1E717.7070707@ti.com> On 10/22/2010 08:48 AM, Arnd Bergmann wrote: > On Friday 22 October 2010 14:39:33 Cyril Chemparathy wrote: >>>> +/* Register Access Helpers */ >>>> +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) >>>> +{ >>>> + return __raw_readl(ssp->regs + reg); >>>> +} >>>> + >>>> +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) >>>> +{ >>>> + __raw_writel(val, ssp->regs + reg); >>>> +} >>> >>> Why are the __raw functions used here? >>> >> >> These registers are to be accessed native endian at all times, and >> therefore the le32 conversion done otherwise is inappropriate. > > Won't that break on out-of-order CPUs that need the extra synchronization > done in readl/writel? > AFAICS, ioremap()ed space on ARMv6 should be strongly ordered. > > ... > Thanks Cyril. From linux at arm.linux.org.uk Fri Oct 22 17:46:12 2010 From: linux at arm.linux.org.uk (Russell King - ARM Linux) Date: Fri, 22 Oct 2010 23:46:12 +0100 Subject: [PATCH v3 01/12] misc: add driver for sequencer serial port In-Reply-To: <4CC1E717.7070707@ti.com> References: <1287694873-12904-1-git-send-email-cyril@ti.com> <20101021161224.b4c0b623.akpm@linux-foundation.org> <4CC18605.80007@ti.com> <201010221448.17728.arnd@arndb.de> <4CC1E717.7070707@ti.com> Message-ID: <20101022224612.GA6079@n2100.arm.linux.org.uk> On Fri, Oct 22, 2010 at 03:33:43PM -0400, Cyril Chemparathy wrote: > On 10/22/2010 08:48 AM, Arnd Bergmann wrote: > > On Friday 22 October 2010 14:39:33 Cyril Chemparathy wrote: > >>>> +/* Register Access Helpers */ > >>>> +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) > >>>> +{ > >>>> + return __raw_readl(ssp->regs + reg); > >>>> +} > >>>> + > >>>> +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) > >>>> +{ > >>>> + __raw_writel(val, ssp->regs + reg); > >>>> +} > >>> > >>> Why are the __raw functions used here? > >>> > >> > >> These registers are to be accessed native endian at all times, and > >> therefore the le32 conversion done otherwise is inappropriate. > > > > Won't that break on out-of-order CPUs that need the extra synchronization > > done in readl/writel? > > > > AFAICS, ioremap()ed space on ARMv6 should be strongly ordered. No. ioremap'd space is device memory on ARMv6 and above, which means if you care about the ordering of writes to device vs memory, you need barriers. Nevertheless, individual reads/writes to devices will be in program order, but writes may be delayed. From chtpatil at gmail.com Tue Oct 26 13:13:02 2010 From: chtpatil at gmail.com (chetan patil) Date: Tue, 26 Oct 2010 23:43:02 +0530 Subject: Default Message-ID: Is there any way to get default settings in DM6446. I changed the bootargs and proper booting not occurring. Please reply asap. Thanks -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From Jon.Povey at racelogic.co.uk Tue Oct 26 21:47:23 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Wed, 27 Oct 2010 03:47:23 +0100 Subject: I want to get the address to download the package ofDavinci-linux-open-source In-Reply-To: <20101022122127.9F8042F17B8@mail0.webapp.51uc.com> Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EEF909F@Cloud.RL.local> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > I interested in davinci,wo I want to get the address of the > package of Davinci-linux-open-source to download for study.thank you Lots of good info on the wiki: http://processors.wiki.ti.com/index.php/DaVinci_GIT_Linux_Kernel#Overview -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From anavatta at imnet.it Wed Oct 27 03:24:42 2010 From: anavatta at imnet.it (Alberto Navatta) Date: Wed, 27 Oct 2010 10:24:42 +0200 Subject: Gnash on TI In-Reply-To: References: Message-ID: <004401cb75b0$6b3dfeb0$41b9fc10$@it> We?re currently working to have Gnash running on DM6446 with GStreamer backend, AGG and SDL. Alberto From: amr ali [mailto:amraldo at hotmail.com] Sent: luned? 25 ottobre 2010 10.24 To: davinci forum Subject: Gnash on TI Did anyone try running on Gnash on DM6446 or any similar package for supporting flash? -- Amr Ali Abdel-Naby Embedded Systems Developer www.embedded-tips.blogspot.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From chtpatil at gmail.com Wed Oct 27 08:35:43 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 19:05:43 +0530 Subject: NFS Message-ID: We need to use cross over cable for booting through NFS host.????? And what should be the configuration in Network manager eth0????? IP-Config: Retrying forever (NFS root)... Sending DHCP requests ...... timed out! EMAC: TX Complete: Starting queue IP-Config: Retrying forever (NFS root)... Sending DHCP requests ...... timed out! EMAC: TX Complete: Starting queue IP-Config: Retrying forever (NFS root)... I get above message and nothing happens after this. HOST IP: 192.168.1.1 (assigned using terminal and manually using network manager) -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Wed Oct 27 09:02:22 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Wed, 27 Oct 2010 09:02:22 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 8:35 AM, chetan patil wrote: > We need to use cross over cable for booting through NFS host.????? No you don't need a cross over cable > And what should be the configuration in Network manager eth0????? > > IP-Config: Retrying forever (NFS root)... > Sending DHCP requests ...... timed out! > EMAC: TX Complete: Starting queue > IP-Config: Retrying forever (NFS root)... > Sending DHCP requests ...... timed out! > EMAC: TX Complete: Starting queue > IP-Config: Retrying forever (NFS root)... > > I get above message and nothing happens after this. Well I will send you the steps that I foww every time that I have to configure my NFS on my Ubuntu desktop Installing NFS Server Run this: sudo apt-get install nfs-kernel-server nfs-common portmap Create a folder in your home directory named "my-nfs" (or anything you want) Edit /etc/exports file as superuser, and add a line below like this: /home/victor/my-nfs *(rw,no_root_squash,sync,no_subtree_check) Restart the NFS service with this command: sudo /etc/init.d/nfs-kernel-server restart Note: Every time you do a change in /etc/exports to a running NFS server, to apply changes run: sudo exportfs -a Hope it helps Victor Rodriguez > > HOST IP: 192.168.1.1 (assigned using terminal and manually using network > manager) > > -- > Regards, > > Chetan Arvind Patil, > +919970018364 > http://sites.google.com/site/chtpatil/ > > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > From chtpatil at gmail.com Wed Oct 27 09:44:14 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 20:14:14 +0530 Subject: My bootargs...that messed up. Message-ID: setenv bootargs video=davincifb:vid0=0,2500K: vid1=0,2500K:osd0=720x576x16,2025K davinci_enc_mngr.ch0_output=COMPOSITE davinci_enc_mngr.ch0_mode=$(videostd) console=ttyS0,115200n8 noinitrd rw ip=dhcp root=/dev/nfs nfsroot=$(nfshost):$(rootpath),nolock mem=118M -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.kondrad at legrand.us Wed Oct 27 09:52:15 2010 From: david.kondrad at legrand.us (david.kondrad at legrand.us) Date: Wed, 27 Oct 2010 10:52:15 -0400 Subject: Problem with new SPI driver In-Reply-To: Message-ID: Greetings: > I tried a quick fix where for transfers larger than 32K. I fixex > bcount to 32K and set ccnt to wcount / 32K. > if( davinci_spi->wcount > 0xFFFF ) > { > if( davinci_spi->wcount & 0x7FFF ) > { > dev_info(sdev, "larger SPI transfers need to be > multiples of 32K\n"); > return -EIO; > } > tx_param.a_b_cnt = 0x8000 << 16 | data_type; > tx_param.ccnt = davinci_spi->wcount / 0x8000; > } > else > { > tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; > tx_param.ccnt = 1; > } > The transfers don't hang but the data above the first 32K is invalid. > Must something different be done to use the ccnt correctly? > Given my board has larger spi flash sectors, I would like to have a > workaround in the driver instead than making sure all applications use > small transfers. Since I don't have the exact source in front of me, I'm winging it so to speak. If the previous code did not use ccnt, then what you need to do depends on the trigger mode of the transfer. I see in the above code that the transfer is using AB-SYNC mode so it is likely that the transfer is setup as a one-shot burst (setting the transfer completion at end of transfer). If you are moving to transferring blocks of AB-SYNC transfers from a manually triggered event, then you must enable intermediate transfer chaining by setting ITCCHEN bit in the options and making sure that the STATIC bit is clear (0). Otherwise, you will only get one block transferred and the transfer will remain pending. Also, you need to set the src and dst 'c' indices correctly so that the controller knows how to increment the src and dst memory locations at the end of ab AB-SYNC transfer. Hope this helps point you in the right direction. Best regards, David -- David Kondrad Software Design Engineer Home Systems Division Legrand, North America david.kondrad at legrand.us www.legrand.us/onq This email, and any document attached hereto, may contain confidential and/or privileged information. If you are not the intended recipient (or have received this email in error) please notify the sender immediately and destroy this email. Any unauthorized, direct or indirect, copying, disclosure, distribution or other use of the material or parts thereof is strictly forbidden. From vm.rod25 at gmail.com Wed Oct 27 09:56:33 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Wed, 27 Oct 2010 09:56:33 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 9:27 AM, chetan patil wrote: > We are using fedora 12. > > And the we are using similar steps except the sudo command which u said. > > Please reply asap. > > On Wed, Oct 27, 2010 at 7:32 PM, Victor Rodriguez > wrote: >> >> On Wed, Oct 27, 2010 at 8:35 AM, chetan patil wrote: >> > We need to use cross over cable for booting through NFS host.????? >> >> >> No you don't need a cross over cable >> >> >> >> > And what should be the configuration in Network manager eth0????? >> > >> > IP-Config: Retrying forever (NFS root)... >> > Sending DHCP requests ...... timed out! >> > EMAC: TX Complete: Starting queue >> > IP-Config: Retrying forever (NFS root)... >> > Sending DHCP requests ...... timed out! >> > EMAC: TX Complete: Starting queue >> > IP-Config: Retrying forever (NFS root)... >> > >> > I get above message and nothing happens after this. >> >> Well I will send you the steps that I foww every time that I have to >> configure my NFS on my Ubuntu desktop >> >> Installing NFS Server >> >> Run this: >> >> sudo apt-get install nfs-kernel-server nfs-common portmap >> >> Create a folder in your home directory named "my-nfs" (or anything you >> want) >> >> Edit /etc/exports file as superuser, and add a line below like this: >> >> /home/victor/my-nfs *(rw,no_root_squash,sync,no_subtree_check) >> >> Restart the NFS service with this command: >> >> sudo /etc/init.d/nfs-kernel-server restart >> >> Note: Every time you do a change in /etc/exports to a running NFS >> server, to apply changes run: >> >> sudo exportfs -a >> >> Hope it helps >> >> Victor Rodriguez >> >> >> > >> > HOST IP: 192.168.1.1 (assigned using terminal and manually using network >> > manager) >> > >> > -- >> > Regards, >> > >> > Chetan Arvind Patil, >> > +919970018364 >> > http://sites.google.com/site/chtpatil/ >> > >> > >> > _______________________________________________ >> > Davinci-linux-open-source mailing list >> > Davinci-linux-open-source at linux.davincidsp.com >> > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source >> > >> > > > > > -- > Regards, > > Chetan Arvind Patil, > +919970018364 > http://sites.google.com/site/chtpatil/ > > HI Chetan AFAIK the NFS should be under a LAN network, so you net to establish a LAN network first Then if NFS is right you should send to the boat loader this information first setenv serverip (your computer ip adrs ) setenv ipaddr (the board ip adrs ) setenv gateway (your network gateway) setenv netmask (your netmask) Then if you are transfering your uImage by tftp do it tftp c0700000 uImage_v1 For the NFS boot args it will be diferent if you have a DHCP or static ip For DHCP setenv bootargs 'console=ttyS2,115200n8 noinitrd rw ip=dhcp root=/dev/nfs nfsroot=192.168.1.1:/home/BLABLA/my_nfs/name-of-the-directory' If DHCP is not available setenv bootargs mem=128M console=ttyS2,115200n8 root=/dev/nfs rw nfsroot=192.168.1.1:/home/BLABLA/my_nfs//name-of-the-directory ip=::::hawkboard:eth0:off nolock,rsize=1024,wsize=1024 rootdelay=2 init=/init Then boot as usual Regards From hebert.marcandre at gmail.com Wed Oct 27 10:17:45 2010 From: hebert.marcandre at gmail.com (=?ISO-8859-1?Q?Marc=2DAndr=E9_H=E9bert?=) Date: Wed, 27 Oct 2010 11:17:45 -0400 Subject: Problem with new SPI driver In-Reply-To: References: Message-ID: Thank you for the information David. I hadn't noticed the ITCCHEN when I checked the DMA doc. Unfortunately I have to put this problem aside for now. But I will have to take another look at it at some point (unless somebody else does). Marc From chtpatil at gmail.com Wed Oct 27 10:19:06 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 20:49:06 +0530 Subject: NFS Message-ID: Sending DHCP requests ., OK IP-Config: Got DHCP answer from 0.0.0.0, my address is 192.168.1.6 IP-Config: Complete: device=eth0, addr=192.168.1.6, mask=255.255.255.0, gw=192.168.1.1, host=192.168.1.6, domain=, nis-domain=(none), bootserver=0.0.0.0, rootserver=192.168.1.5, rootpath= Looking up port of RPC 100003/2 on 192.168.1.5 Looking up port of RPC 100005/1 on 192.168.1.5 VFS: Mounted root (nfs filesystem). Freeing init memory: 532K FATAKernel panic - not syncing: Attempted to kill init! L: kernel too ol d I got above message while booting DM6446. My env variables are: TirDavinci_EVM# printenv bootdelay=3 baudrate=115200 bootfile="uImage" ethaddr=ff:ff:ff:ff:ff:ff ipaddr=192.168.0.51 bootcmd=cp.b 0x21D0000 0x85000000 0xaf42d3 ;bootm 0x2050000 rootpath=/home/chetanpatil/workdir/filesys nfshost=192.168.1.5 bootargs=mem=120M console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.1.5:/home/chetanpatil/workdir/filesys ip=dhcp stdin=serial stdout=serial stderr=serial serverip=192.168.1.5 gateway=192.168.1.255 netmask=255.255.255.0 Environment size: 441/8188 bytes Not getting what to do. -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From aelder at audioscience.com Wed Oct 27 10:32:42 2010 From: aelder at audioscience.com (Andrew Elder) Date: Wed, 27 Oct 2010 11:32:42 -0400 Subject: Problem with new SPI driver In-Reply-To: References: Message-ID: <4CC8461A.1020903@audioscience.com> On 10/27/2010 10:52 AM, david.kondrad at legrand.us wrote: > Greetings: > >> I tried a quick fix where for transfers larger than 32K. I fixex >> bcount to 32K and set ccnt to wcount / 32K. >> if( davinci_spi->wcount> 0xFFFF ) >> { >> if( davinci_spi->wcount& 0x7FFF ) >> { >> dev_info(sdev, "larger SPI transfers need to be >> multiples of 32K\n"); >> return -EIO; >> } >> tx_param.a_b_cnt = 0x8000<< 16 | data_type; >> tx_param.ccnt = davinci_spi->wcount / 0x8000; >> } >> else >> { >> tx_param.a_b_cnt = davinci_spi->wcount<< 16 | data_type; >> tx_param.ccnt = 1; >> } >> The transfers don't hang but the data above the first 32K is invalid. >> Must something different be done to use the ccnt correctly? >> Given my board has larger spi flash sectors, I would like to have a >> workaround in the driver instead than making sure all applications use >> small transfers. sprugp9b.pdf indicates that you need to also set SRC_DST_CIDX so that the source pointer is incremented correctly when CCNT is decremented. - Andrew > Since I don't have the exact source in front of me, > I'm winging it so to speak. > > If the previous code did not use ccnt, then what you need to do > depends on the trigger mode of the transfer. > > I see in the above code that the transfer is using AB-SYNC mode so it > is likely that the transfer is setup as a one-shot burst (setting the > transfer completion at end of transfer). > > If you are moving to transferring blocks of AB-SYNC transfers from a > manually triggered event, then you must enable intermediate transfer > chaining by setting ITCCHEN bit in the options and making sure that > the STATIC bit is clear (0). > > Otherwise, you will only get one block transferred and the transfer > will remain pending. > > Also, you need to set the src and dst 'c' indices correctly so that > the controller knows how to increment the src and dst memory locations > at the end of ab AB-SYNC transfer. > > Hope this helps point you in the right direction. > > Best regards, > David > > -- > David Kondrad > Software Design Engineer > Home Systems Division > Legrand, North America > > david.kondrad at legrand.us > www.legrand.us/onq > > This email, and any document attached hereto, may contain > confidential and/or privileged information. If you are not the > intended recipient (or have received this email in error) please > notify the sender immediately and destroy this email. Any > unauthorized, direct or indirect, copying, disclosure, distribution > or other use of the material or parts thereof is strictly > forbidden. > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > From schen at mvista.com Wed Oct 27 10:38:30 2010 From: schen at mvista.com (Steve Chen) Date: Wed, 27 Oct 2010 10:38:30 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 10:19 AM, chetan patil wrote: > Sending DHCP requests ., OK > IP-Config: Got DHCP answer from 0.0.0.0, my address is 192.168.1.6 > IP-Config: Complete: > ????? device=eth0, addr=192.168.1.6, mask=255.255.255.0, gw=192.168.1.1, > ???? host=192.168.1.6, domain=, nis-domain=(none), > ???? bootserver=0.0.0.0, rootserver=192.168.1.5, rootpath= > Looking up port of RPC 100003/2 on 192.168.1.5 > Looking up port of RPC 100005/1 on 192.168.1.5 > VFS: Mounted root (nfs filesystem). > Freeing init memory: 532K > FATAKernel panic - not syncing: Attempted to kill init! > L: kernel too ol d ^^^^^^^^^^ Try a newer kernel? From schen at mvista.com Wed Oct 27 10:51:42 2010 From: schen at mvista.com (Steve Chen) Date: Wed, 27 Oct 2010 10:51:42 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 10:40 AM, chetan patil wrote: > How?? You can find some useful info here. http://processors.wiki.ti.com/index.php/Linux_Toolchain > > Kernel of DM6446 is corrupted?? The message basically is saying that the kernel you are using to boot DM6446 is too old for the file system. Your choices are 1. Use a newer kernel 2. Use an older filesystem that would work with your kernel version. Steve From schen at mvista.com Wed Oct 27 11:59:22 2010 From: schen at mvista.com (Steve Chen) Date: Wed, 27 Oct 2010 11:59:22 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 11:36 AM, chetan patil wrote: > I want to boot the borad using NFS. > > My Dm64446 has???? ?? :::?? Linux-2.6.10_mvl401-davinci_evm That is an old kernel :) > My fedora 12 host has :::?? kernel version 2.6.32 Your host is fine. > I think updating kernel of DM6446 is risky business. > > Is there any other option. > And you sure we need to update kernel only? I assume you have a files system that boots on the DM6446 EVM hard drive or on a server somewhere. You can use that for NFS root. You don't want to use any other filesystems for that kernel because they are not likely to work. > > Please check page no. 4-11 of attached doc. > Is there any problem with the target filesys with permission set for writing > to the shared area. Permission will be correct if you follow the steps listed. Steve From chtpatil at gmail.com Wed Oct 27 12:05:24 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 22:35:24 +0530 Subject: NFS In-Reply-To: References: Message-ID: Our Set up: *Host* = Dell Laptop With fedora 12. We installed DVSDK 2.0 ( http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_2_00/latest/index_FDS.html ). Host is connected to DM6446 via serial cable. HOST is also connected to a switch (router) and from that switch (router) is also connected to DM6446. The ip address provided by switch is dynamically allocated. Now monta vista version is 4.0 professional edition on DM6446. No peripherals are attached to Dm6446. NFS we wanted to set up so that DM6446 uses HOST as memory and also to execute our executables. Hope you understood our set up. Dm6446 ip is 192.168.1.6 and while using ping the board is responding. On Wed, Oct 27, 2010 at 10:29 PM, Steve Chen wrote: > On Wed, Oct 27, 2010 at 11:36 AM, chetan patil wrote: > > I want to boot the borad using NFS. > > > > My Dm64446 has ::: Linux-2.6.10_mvl401-davinci_evm > > That is an old kernel :) > > > My fedora 12 host has ::: kernel version 2.6.32 > > Your host is fine. > > > > I think updating kernel of DM6446 is risky business. > > > > Is there any other option. > > And you sure we need to update kernel only? > > I assume you have a files system that boots on the DM6446 EVM hard > drive or on a server somewhere. You can use that for NFS root. You > don't want to use any other filesystems for that kernel because they > are not likely to work. > > > > > Please check page no. 4-11 of attached doc. > > Is there any problem with the target filesys with permission set for > writing > > to the shared area. > > Permission will be correct if you follow the steps listed. > > Steve > -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Wed Oct 27 12:12:42 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Wed, 27 Oct 2010 12:12:42 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 10:51 AM, Steve Chen wrote: > On Wed, Oct 27, 2010 at 10:40 AM, chetan patil wrote: >> How?? > > You can find some useful info here. > > http://processors.wiki.ti.com/index.php/Linux_Toolchain > >> >> Kernel of DM6446 is corrupted?? > > The message basically is saying that the kernel you are using to boot > DM6446 is too old for the file system. ?Your choices are > 1. ?Use a newer kernel > 2. ?Use an older filesystem that would work with your kernel version. > > Steve > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > Hi Chetan Here is step by step how to set up your host computer * ARM Cross Compiler - For Linux/U-boot 2.3. Downloading an Installer You can download Sourcery G++ Lite from the Sourcery G++ web site1 the .tar.bz2 extension. http://www.codesourcery.com/sgpp/lite/arm/portal/release1033 .4.3. Installing Sourcery G++ Lite from a Compressed Archive You do not need to be a system administrator to install Sourcery G++ Lite from a compressed archive. You may install Sourcery G++ Lite using any user account and in any directory to which you have write access. This guide assumes that you have decided to install Sourcery G++ Lite in the $HOME/ CodeSourcery subdirectory of your home directory and that the filename of the package you have downloaded is /path/to/package.tar.bz2. After installation the toolchain will be in $HOME/CodeSourcery/sourceryg++-2009q3. First, uncompress the package file: > bunzip2 /path/to/package.tar.bz2 Next, create the directory in which you wish to install the package: > mkdir -p $HOME/CodeSourcery Change to the installation directory: > cd $HOME/CodeSourcery Unpack the package: > tar xf /path/to/package.tar Edit your .bashrc file wit adding this (adapt toolchain path in case you have a different one): PATH=$HOME/CodeSourcery/Sourcery_G++/bin:$PATH export PATH You can test that your PATH is set up correctly by running the following command: > arm-none-linux-gnueabi-g++ -v Verify that the last line of the output contains: Sourcery G++ Lite 2009q3-67. Then download the kernel source code git-clone git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git host > make distclean host > make ARCH=arm davinci_all_defconfig host > make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage Open minicom and then trasnfer the uImage byt tftp to the board and the bootargs like before but for that you shoul stop automatic boot by pressing enter or any other key U-Boot 2009.01 (Dec 22 2009 - 10:04:02) DRAM: 128 MB NAND: NAND device: Manufacturer ID: 0x2c, Chip ID: 0xa1 (Micron NAND 128MiB 1,8V 8-bit) Bad block table not found for chip 0 Bad block table not found for chip 0 Bad block table written to 0x07fe0000, version 0x01 Bad block table written to 0x07fc0000, version 0x01 128 MiB In: serial Out: serial Err: serial ARM Clock : 300000000 Hz DDR Clock : 150000000 Hz Ethernet PHY: GENERIC @ 0x07 Hit any key to stop autoboot: 0 hawkboard.org > setenv serverip 10.79.0.44 hawkboard.org > setenv ipaddr 10.79.0.9 hawkboard.org > setenv gateway 10.79.0.1 hawkboard.org > setenv netmask 255.255.255.0 hawkboard.org > savenev Unknown command 'savenev' - try 'help' hawkboard.org > saveenv Saving Environment to NAND... Erasing Nand... Erasing at 0x0 -- 100% complete. Writing to Nand... done hawkboard.org > tftp c0700000 uImage_v1 TFTP from server 10.79.0.44; our IP address is 10.79.0.9 Filename 'uImage_v1'. Load address: 0xc0700000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ##################################################### done Bytes transferred = 1934036 (1d82d4 hex) hawkboard.org > setenv bootargs 'console=ttyS2,115200n8 noinitrd rw ip=dhcp root=/dev/nfs nfsroot=10.79.0.44:/home/victor/my-nfs/alsa-12c-hawk' hawkboard.org > bootm 0xc0700000 AIS U-BootLoader is already flashed ## Booting kernel from Legacy Image at c0700000 ... Image Name: Linux-2.6.32-rc6-00079-g55996fd- Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1933972 Bytes = 1.8 MB Load Address: c0008000 Entry Point: c0008000 Verifying Checksum ... OK Loading Kernel Image ... OK OK Starting kernel ... Linux version 2.6.32-rc6-00079-g55996fd-dirty (root at khasim-laptop) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #2 PREEMPT Thu Nov 26 02:14:24 IST 200 9 From schen at mvista.com Wed Oct 27 13:22:19 2010 From: schen at mvista.com (Steve Chen) Date: Wed, 27 Oct 2010 13:22:19 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 12:05 PM, chetan patil wrote: > Our Set up: > > > Host = Dell Laptop With fedora 12. We installed DVSDK 2.0 > (http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_2_00/latest/index_FDS.html). DVSDK2.0 uses 2.6.18 kernel, and you have a 2.6.10 kernel. However, steps to set up are the same. > > Host is connected to DM6446 via serial cable. HOST is also connected to a > switch (router) and from that switch (router) is also connected to DM6446. > > The ip address provided by switch is dynamically allocated. > > Now monta vista version is 4.0 professional edition on DM6446. > > No peripherals are attached to Dm6446. > > NFS we wanted to set up so that DM6446 uses HOST as memory and also to > execute > our executables. > > Hope you understood our set up. Yes, I understand your setup as it is quite standard. > > Dm6446 ip is 192.168.1.6 and while using ping the board is responding. Yes, this is expected since your network setup is fine. It is the kernel/root filesystem version incompatibility that is causing the problem. Where do you get the kernel? Is there a root filesystem that comes with that kernel? I would say the steps Victor outlined in his e-mail is the easy way to boot the board. If the purpose is to avoid kernel upgrade a all cost, your only option is to locate a filesystem that works with the 2.6.10 kernel. Steve From chtpatil at gmail.com Wed Oct 27 13:28:22 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 23:58:22 +0530 Subject: NFS In-Reply-To: References: Message-ID: Sir we haven't touched anything related to kernel. We wanted that through NFS we can share the directory where to stored our executable file of hello world program. But that seems to be difficult task. As we getting n number of errors as mentioend above. Is it necessary to instal said DVDSK filed for developing purposre. As we did DVSDK installation so that task become quit easy.?? What should be installed on HOST to start developing ?? we even tried USB on dm6446 and some how managed to mount but the one file in pendrive which is hello world is not working after using ./hello command. DOn't know what to do. On Wed, Oct 27, 2010 at 11:52 PM, Steve Chen wrote: > On Wed, Oct 27, 2010 at 12:05 PM, chetan patil wrote: > > Our Set up: > > > > > > Host = Dell Laptop With fedora 12. We installed DVSDK 2.0 > > ( > http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/dvsdk/DVSDK_2_00/latest/index_FDS.html > ). > > DVSDK2.0 uses 2.6.18 kernel, and you have a 2.6.10 kernel. However, > steps to set up are the same. > > > > > Host is connected to DM6446 via serial cable. HOST is also connected to a > > switch (router) and from that switch (router) is also connected to > DM6446. > > > > The ip address provided by switch is dynamically allocated. > > > > Now monta vista version is 4.0 professional edition on DM6446. > > > > No peripherals are attached to Dm6446. > > > > NFS we wanted to set up so that DM6446 uses HOST as memory and also to > > execute > > our executables. > > > > Hope you understood our set up. > > Yes, I understand your setup as it is quite standard. > > > > > Dm6446 ip is 192.168.1.6 and while using ping the board is responding. > > Yes, this is expected since your network setup is fine. It is the > kernel/root filesystem version incompatibility that is causing the > problem. Where do you get the kernel? Is there a root filesystem > that comes with that kernel? I would say the steps Victor outlined in > his e-mail is the easy way to boot the board. If the purpose is to > avoid kernel upgrade a all cost, your only option is to locate a > filesystem that works with the 2.6.10 kernel. > > Steve > -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From schen at mvista.com Wed Oct 27 14:17:47 2010 From: schen at mvista.com (Steve Chen) Date: Wed, 27 Oct 2010 14:17:47 -0500 Subject: NFS In-Reply-To: References: Message-ID: On Wed, Oct 27, 2010 at 1:28 PM, chetan patil wrote: > Sir we haven't touched anything related to kernel. Ok, I understand. > We wanted that through NFS we can share the directory where to stored our > executable file of hello world program. Ok, actually, you can just NFS mount a single directory instead of the entire rootfs. May be easier that way. > But that seems to be difficult task. As we getting n number of errors as > mentioend above. A single NFS mounted rootfs can not be shared by multiple target (dm6446 EVM). > Is it necessary to instal said DVDSK filed for developing purposre. > > As we did DVSDK installation so that task become quit easy.?? > > What should be installed on HOST to start developing ?? At minimum, you need an editor and cross tools (compilers, libraries, etc.). You can get it either from SDK or community. > > we even tried USB on dm6446 and some how managed to mount but the one file > in pendrive which is hello world is not working after using ./hello command. This implies that you can boot the target complete using non-NFS method. Consider doing a NFS mount directory for shared application programs. I hope this provide some ideas for progress. Steve From Jon.Povey at racelogic.co.uk Wed Oct 27 19:56:13 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Thu, 28 Oct 2010 01:56:13 +0100 Subject: NFS In-Reply-To: Message-ID: <70E876B0EA86DD4BAF101844BC814DFE093EEF92C2@Cloud.RL.local> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > On Wed, Oct 27, 2010 at 1:28 PM, chetan patil > wrote: >> we even tried USB on dm6446 and some how managed to mount but the >> one file in pendrive which is hello world is not working after using >> ./hello command. > > This implies that you can boot the target complete using non-NFS > method. Consider doing a NFS mount directory for shared application > programs. Also, for DM355 at least, the ARM ABI changed between the MV toolchain and the current recommended CodeSourcery one. So the binaries are incompatible - don't run on the other system. I.e. you need a cross-toolchain that matches your kernel. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From nsekhar at ti.com Thu Oct 28 09:04:10 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 28 Oct 2010 19:34:10 +0530 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: Hi Victor, Sorry for jumping late on this. Some comments below: On Tue, Oct 19, 2010 at 23:36:19, vm.rod25 at gmail.com wrote: > From: Victor Rodriguez > > This patch adds EMAC support for the Hawkboard-L138 system > > Signed-off-by: Victor Rodriguez > --- > arch/arm/mach-davinci/board-omapl138-hawk.c | 47 +++++++++++++++++++++++++++ > 1 files changed, 47 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > index c472dd8..8633245 100644 > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > @@ -19,6 +19,51 @@ > > #include > #include > +#include > + > +#define HAWKBOARD_PHY_ID "0:07" > + > +static short omapl138_hawk_mii_pins[] __initdata = { > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > + DA850_MDIO_D, > + -1 -1 need not be a new line. In any case, please include a ',' after it. > +}; > + > +static __init void omapl138_hawk_config_emac(void) > +{ > + void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); > + int ret; > + u32 val; > + struct davinci_soc_info *soc_info = &davinci_soc_info; > + > + if (!machine_is_omapl138_hawkboard()) > + return; This is not required since this function is called only on a hawkboard. Thanks, Sekhar From vm.rod25 at gmail.com Thu Oct 28 09:18:09 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 09:18:09 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 9:04 AM, Nori, Sekhar wrote: > Hi Victor, > > Sorry for jumping late on this. Some comments below: > On Tue, Oct 19, 2010 at 23:36:19, vm.rod25 at gmail.com wrote: >> From: Victor Rodriguez >> >> This patch adds EMAC support for the Hawkboard-L138 system >> >> Signed-off-by: Victor Rodriguez >> --- >> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 47 +++++++++++++++++++++++++++ >> ?1 files changed, 47 insertions(+), 0 deletions(-) >> >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index c472dd8..8633245 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -19,6 +19,51 @@ >> >> ?#include >> ?#include >> +#include >> + >> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? "0:07" >> + >> +static short omapl138_hawk_mii_pins[] __initdata = { >> + ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >> + ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >> + ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >> + ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >> + ? ? DA850_MDIO_D, >> + ? ? -1 > > -1 need not be a new line. In any case, please include a ',' after it. > >> +}; >> + >> +static __init void omapl138_hawk_config_emac(void) >> +{ >> + ? ? void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); >> + ? ? int ret; >> + ? ? u32 val; >> + ? ? struct davinci_soc_info *soc_info = &davinci_soc_info; >> + >> + ? ? if (!machine_is_omapl138_hawkboard()) >> + ? ? ? ? ? ? return; > > This is not required since this function is called only on > a hawkboard. > > Thanks, > Sekhar > > Do not worry , and thanks a lot for the comments . I really appreciate it. Thanks Sincerely yours Victor Rodriguez From nsekhar at ti.com Thu Oct 28 09:18:31 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 28 Oct 2010 19:48:31 +0530 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 19:34:10, Nori, Sekhar wrote: > Hi Victor, > > Sorry for jumping late on this. Some comments below: > > On Tue, Oct 19, 2010 at 23:36:19, vm.rod25 at gmail.com wrote: > > From: Victor Rodriguez > > > > This patch adds EMAC support for the Hawkboard-L138 system > > > > Signed-off-by: Victor Rodriguez > > --- > > arch/arm/mach-davinci/board-omapl138-hawk.c | 47 +++++++++++++++++++++++++++ > > 1 files changed, 47 insertions(+), 0 deletions(-) > > > > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c > > index c472dd8..8633245 100644 > > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c > > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c > > @@ -19,6 +19,51 @@ > > > > #include > > #include > > +#include > > + > > +#define HAWKBOARD_PHY_ID "0:07" > > + > > +static short omapl138_hawk_mii_pins[] __initdata = { > > + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, > > + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, > > + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, > > + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, > > + DA850_MDIO_D, > > + -1 > > -1 need not be a new line. In any case, please include a ',' after it. The justification for a ',' in the end is that it makes it easier to add new initialization elements. Since -1 is going to be the last one anyway, please ignore this comment. Thanks, Sekhar From vm.rod25 at gmail.com Thu Oct 28 09:21:28 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 09:21:28 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 9:18 AM, Nori, Sekhar wrote: > On Thu, Oct 28, 2010 at 19:34:10, Nori, Sekhar wrote: >> Hi Victor, >> >> Sorry for jumping late on this. Some comments below: >> >> On Tue, Oct 19, 2010 at 23:36:19, vm.rod25 at gmail.com wrote: >> > From: Victor Rodriguez >> > >> > This patch adds EMAC support for the Hawkboard-L138 system >> > >> > Signed-off-by: Victor Rodriguez >> > --- >> > ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 47 +++++++++++++++++++++++++++ >> > ?1 files changed, 47 insertions(+), 0 deletions(-) >> > >> > diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c >> > index c472dd8..8633245 100644 >> > --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> > +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> > @@ -19,6 +19,51 @@ >> > >> > ?#include >> > ?#include >> > +#include >> > + >> > +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? "0:07" >> > + >> > +static short omapl138_hawk_mii_pins[] __initdata = { >> > + ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >> > + ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >> > + ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >> > + ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >> > + ? ? DA850_MDIO_D, >> > + ? ? -1 >> >> -1 need not be a new line. In any case, please include a ',' after it. > > The justification for a ',' in the end is that it makes it easier > to add new initialization elements. Since -1 is going to be > the last one anyway, please ignore this comment. > > Thanks, > Sekhar > > Ok so let me see if I understand The only change that I should do is to remove > + if (!machine_is_omapl138_hawkboard()) > + return; right ? Regards Victor From nsekhar at ti.com Thu Oct 28 09:34:07 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 28 Oct 2010 20:04:07 +0530 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 19:51:28, Victor Rodriguez wrote: > Ok so let me see if I understand The only change that I should do is to remove > > > + if (!machine_is_omapl138_hawkboard()) > > + return; > > right ? > Yes. Thanks, Sekhar From anavatta at imnet.it Thu Oct 28 09:45:30 2010 From: anavatta at imnet.it (Alberto Navatta) Date: Thu, 28 Oct 2010 16:45:30 +0200 Subject: DM6446 and WVGA display problem References: Message-ID: <008d01cb76ae$c88f4250$59adc6f0$@it> Hi, We're experiencing a strange behavior on our DM6446 board with a WVGA LCD digital display (display max resolution is 800 x 480 pixels): . VID0 and VID1 windows work fine, we can successfully achieve the 800 x 480 resolution . OSD0 doesn't work properly: we're able to see only 712 pixels of the 800 available, the last column visible is column 712 and it is positioned at the end of the visible area on the display and columns from 712 to 800 are not visible (it looks like if this window is stretched horizzontally) We're not able to identify any possible source of the problem: . We expect the VPBE is correctly configured to support our LCD display (Output in RGB888, Syncs, LCD_OE, VCLK and other signals seems to be good as seen outside the Davinci) . As said the VID0 and VID1 windows are correctly displayed on the screen (if there was a misconfiguration of the Video Encoder we had to see the problem on all the windows) . If we switch the resolution to use the display at a standard VGA resolution (e.g. by changing HSTART, HVALID, HSPLS, HSDLY, etc. to see the display as a standard 640 x 480 pixel display), we still have the same behavior: VID0 and VID1 are ok, OSD0 displays less than 640 columns horizontally and the OSD0 window is stretched to cover the whole visible display area Does anyone has experienced a similar problem or has an idea of what we're doing wrong/what could lead to this behavior? Regards, Alberto Navatta -------------- next part -------------- An HTML attachment was scrubbed... URL: From vm.rod25 at gmail.com Thu Oct 28 10:26:08 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 10:26:08 -0500 Subject: Which is going to be the latest kernel version for this year Message-ID: Hey I want to know which is going to be the latest kernel version for this year Is possible to have the v2.6.37 merge window but do you think that could be possible to have v2.6.38 ? Thanks for your help Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 28 11:24:44 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 11:24:44 -0500 Subject: Resend a patch Message-ID: HI I have changed a patch and now is ready and running but I have a question if the new patch apply fine and any other patches of the series has been changed should i send all the patches again like patchv6 ? or should i send this EMAC patch like resend patch ? I do not thick so but if it is necessary I will do it Thanks and regards Victor Rodriguez From chtpatil at gmail.com Thu Oct 28 11:40:39 2010 From: chtpatil at gmail.com (chetan patil) Date: Thu, 28 Oct 2010 22:10:39 +0530 Subject: SD card Message-ID: I copied my hello world program in SD card. Then putted that into Dm6446 but not able to access the files. sd card is already mounted. How to access the contents of sd card. #cd mnt # ls sd #cd sd #ls # this is what i get. please reply asap. -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: From sshtylyov at mvista.com Thu Oct 28 10:54:01 2010 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 28 Oct 2010 19:54:01 +0400 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: <4CC99C99.5010207@mvista.com> Hello. On 28-10-2010 18:04, Nori, Sekhar wrote: > Sorry for jumping late on this. Some comments below: >> From: Victor Rodriguez >> This patch adds EMAC support for the Hawkboard-L138 system >> Signed-off-by: Victor Rodriguez >> --- >> arch/arm/mach-davinci/board-omapl138-hawk.c | 47 +++++++++++++++++++++++++++ >> 1 files changed, 47 insertions(+), 0 deletions(-) >> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c >> index c472dd8..8633245 100644 >> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >> @@ -19,6 +19,51 @@ >> >> #include >> #include >> +#include >> + >> +#define HAWKBOARD_PHY_ID "0:07" >> + >> +static short omapl138_hawk_mii_pins[] __initdata = { >> + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >> + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >> + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >> + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >> + DA850_MDIO_D, >> + -1 > -1 need not be a new line. In any case, please include a ',' after it. Why is that? It's always a last entry in the array. WBR, Sergei From vm.rod25 at gmail.com Thu Oct 28 13:34:40 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 13:34:40 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <4CC99C99.5010207@mvista.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> <4CC99C99.5010207@mvista.com> Message-ID: On Thu, Oct 28, 2010 at 10:54 AM, Sergei Shtylyov wrote: > Hello. > > On 28-10-2010 18:04, Nori, Sekhar wrote: > >> Sorry for jumping late on this. Some comments below: > >>> From: Victor Rodriguez > >>> This patch adds EMAC support for the Hawkboard-L138 system > >>> Signed-off-by: Victor Rodriguez >>> --- >>> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 47 >>> +++++++++++++++++++++++++++ >>> ?1 files changed, 47 insertions(+), 0 deletions(-) > >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index c472dd8..8633245 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> @@ -19,6 +19,51 @@ >>> >>> ?#include >>> ?#include >>> +#include >>> + >>> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? "0:07" >>> + >>> +static short omapl138_hawk_mii_pins[] __initdata = { >>> + ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >>> + ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >>> + ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >>> + ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >>> + ? ? DA850_MDIO_D, >>> + ? ? -1 > >> -1 need not be a new line. In any case, please include a ',' after it. > > ? Why is that? It's always a last entry in the array. > > WBR, Sergei > Sergei Nori Sekhar explained that in the last comment. he said that there is no change on ti Regards Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 28 13:54:29 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 13:54:29 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <4CC99C99.5010207@mvista.com> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> <4CC99C99.5010207@mvista.com> Message-ID: On Thu, Oct 28, 2010 at 10:54 AM, Sergei Shtylyov wrote: > Hello. > > On 28-10-2010 18:04, Nori, Sekhar wrote: > >> Sorry for jumping late on this. Some comments below: > >>> From: Victor Rodriguez > >>> This patch adds EMAC support for the Hawkboard-L138 system > >>> Signed-off-by: Victor Rodriguez >>> --- >>> ?arch/arm/mach-davinci/board-omapl138-hawk.c | ? 47 >>> +++++++++++++++++++++++++++ >>> ?1 files changed, 47 insertions(+), 0 deletions(-) > >>> diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> index c472dd8..8633245 100644 >>> --- a/arch/arm/mach-davinci/board-omapl138-hawk.c >>> +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c >>> @@ -19,6 +19,51 @@ >>> >>> ?#include >>> ?#include >>> +#include >>> + >>> +#define HAWKBOARD_PHY_ID ? ? ? ? ? ? "0:07" >>> + >>> +static short omapl138_hawk_mii_pins[] __initdata = { >>> + ? ? DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, >>> + ? ? DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, >>> + ? ? DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, >>> + ? ? DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, >>> + ? ? DA850_MDIO_D, >>> + ? ? -1 > >> -1 need not be a new line. In any case, please include a ',' after it. > > ? Why is that? It's always a last entry in the array. > > WBR, Sergei > Hey Sergei these patches have been tested by Rene Gonzales and ack by Liam and Mark Brown , I am going to send the patches V6 because of this change. I have been rechecking the code and seems that there is no problem on it, do you have any other comment before i send the series of patches v6 ? Thanks a lot for your comments Really appreciated Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 28 14:01:27 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 14:01:27 -0500 Subject: [alsa-devel] [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <20101021222828.GC9346@sirena.org.uk> References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> <20101021222828.GC9346@sirena.org.uk> Message-ID: On Thu, Oct 21, 2010 at 5:28 PM, Mark Brown wrote: > On Tue, Oct 19, 2010 at 01:06:21PM -0500, vm.rod25 at gmail.com wrote: >> From: Victor Rodriguez >> >> This patch adds ASoC support for the Hawkboard-L138 system >> >> Signed-off-by: Victor Rodriguez > > Acked-by: Mark Brown > > Please do remember to CC maintainers on patches so they see them. > Hi Mark I am going to resend this series of patches because of one small coding stile problem, is this ok for you if I resend this patches with CC to you and alsa mailing list ? Thanks Victor Rodriguez From broonie at opensource.wolfsonmicro.com Thu Oct 28 14:35:51 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Thu, 28 Oct 2010 12:35:51 -0700 Subject: [alsa-devel] [PATCH v5 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-4-git-send-email-vm.rod25@gmail.com> <20101021222828.GC9346@sirena.org.uk> Message-ID: <20101028193550.GC2502@opensource.wolfsonmicro.com> On Thu, Oct 28, 2010 at 02:01:27PM -0500, Victor Rodriguez wrote: > On Thu, Oct 21, 2010 at 5:28 PM, Mark Brown > > Please do remember to CC maintainers on patches so they see them. > Hi Mark I am going to resend this series of patches because of one > small coding stile problem, is this ok for you if I resend this > patches with CC to you and alsa mailing list ? Yes, please CC myself and Liam on all ASoC patches. From caglarakyuz at gmail.com Fri Oct 29 02:36:06 2010 From: caglarakyuz at gmail.com (Caglar Akyuz) Date: Fri, 29 Oct 2010 10:36:06 +0300 Subject: DM6446 and WVGA display problem In-Reply-To: <008d01cb76ae$c88f4250$59adc6f0$@it> References: <008d01cb76ae$c88f4250$59adc6f0$@it> Message-ID: <201010291036.06557.caglarakyuz@gmail.com> On Thursday 28 October 2010 05:45:30 pm Alberto Navatta wrote: > Hi, > > > > We're experiencing a strange behavior on our DM6446 board with a WVGA LCD > digital display (display max resolution is 800 x 480 pixels): > > . VID0 and VID1 windows work fine, we can successfully achieve the > 800 x 480 resolution > > . OSD0 doesn't work properly: we're able to see only 712 pixels of > the 800 available, the last column visible is column 712 and it is > positioned at the end of the visible area on the display and columns from > 712 to 800 are not visible (it looks like if this window is stretched > horizzontally) > > > > We're not able to identify any possible source of the problem: > > . We expect the VPBE is correctly configured to support our LCD > display (Output in RGB888, Syncs, LCD_OE, VCLK and other signals seems to > be good as seen outside the Davinci) > > . As said the VID0 and VID1 windows are correctly displayed on the > screen (if there was a misconfiguration of the Video Encoder we had to see > the problem on all the windows) > > . If we switch the resolution to use the display at a standard VGA > resolution (e.g. by changing HSTART, HVALID, HSPLS, HSDLY, etc. to see the > display as a standard 640 x 480 pixel display), we still have the same > behavior: VID0 and VID1 are ok, OSD0 displays less than 640 columns > horizontally and the OSD0 window is stretched to cover the whole visible > display area > > > > Does anyone has experienced a similar problem or has an idea of what we're > doing wrong/what could lead to this behavior? > > Regards, > Hi, FYI, we're using WVGA display with DM6446 as well and we don't see any problem with 2.6.32 Arago kernel. Regards, Caglar > Alberto Navatta > From swapashtekar at gmail.com Fri Oct 29 02:57:30 2010 From: swapashtekar at gmail.com (Swapnil Ashtekar) Date: Fri, 29 Oct 2010 13:27:30 +0530 Subject: SD card..... Message-ID: Hey, I want to find whether my DM6446 kernel will work with the SD card device drivers using Dynamically Loadable Kernel Module ? Also suggest some patch files to link between the fedora and monta vista linux ? Please do reply asap. -- Regards Swapnil Ashtekar -------------- next part -------------- An HTML attachment was scrubbed... URL: From sureshs at silvanlabs.com Fri Oct 29 07:33:16 2010 From: sureshs at silvanlabs.com (Suresh Somasekharappa) Date: Fri, 29 Oct 2010 18:03:16 +0530 Subject: Problem in openRTSP client on DM365 IPNC Message-ID: Hi, I am trying to receive a h264 encoded stream from live555 on dm365. I am getting the following error. Failed to get a SDP description from URL "rtsp:// 192.168.1.223:8557/PSIA/Streaming/channels/2?videoCodecType=H.264": Failed to read response: No such file or directory but with same URL, I could play from the VLC player playing on my laptop. Any help would be greatly appreciated. Thanks and Regards, Suresh -------------- next part -------------- An HTML attachment was scrubbed... URL: From nsekhar at ti.com Fri Oct 29 07:59:11 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Fri, 29 Oct 2010 18:29:11 +0530 Subject: SD card..... In-Reply-To: References: Message-ID: Hi Swapnil, On Fri, Oct 29, 2010 at 13:27:30, Swapnil Ashtekar wrote: > Hey, > I want to find whether my DM6446 kernel will work with the SD > card device drivers using Dynamically Loadable Kernel Module ? Are you testing with latest 2.6.36 kernel? If you faced any issues, you can report it to this list with logs. > > Also suggest some patch files to link between the fedora and monta vista > linux ? Not sure I understood this one. Thanks, Sekhar From chensu.main at 263.net Fri Oct 29 08:14:38 2010 From: chensu.main at 263.net (chensu.main) Date: Fri, 29 Oct 2010 21:14:38 +0800 Subject: Need help to compile WINCE version DSPLINK for omapl138 Message-ID: <201010292114367504596@263.net> Hi all, I have download wince-portted-version DSPlink , and the filename is dsplink_1_65_00_03.tar.gz In the doc(InstallGuide_WinCE_OMAPL138.pdf ) , I have some question? Which tool chain should I use? I only enter dos window from VS2005's build menu.and I also modify some PATH by set path=C:\ti-tools\bios\xdctools;C:\ti-tools\bios\xdctools\bin;%path% set path=D:\dsplink\etc\host\scripts\msdos;c:\perl\bin;%path%; But compilling process cann't be continued.the error info is D:\dsplink\gpp\src>make debug [SRC ] ======= DIRS ================== INCLUDE ============ make[1]: Entering directory `D:/dsplink/gpp/src/arch' [ARCH ] ------- DIRS ------------------ INCLUDE ------------ C:Perl\bin\perl: not found make[1]: *** [D:\dsplink\\gpp\\export\\INCLUDE] Error 127 make[1]: Leaving directory `D:/dsplink/gpp/src/arch' make: *** [arch.dirinc] Error 2 Can anyone give me a Guide , or some indication? Thanks very much. 2010-10-29 chensu.main -------------- next part -------------- An HTML attachment was scrubbed... URL: From hebert.marcandre at gmail.com Fri Oct 29 10:02:24 2010 From: hebert.marcandre at gmail.com (=?ISO-8859-1?Q?Marc=2DAndr=E9_H=E9bert?=) Date: Fri, 29 Oct 2010 11:02:24 -0400 Subject: Problem with new SPI driver In-Reply-To: <4CC8461A.1020903@audioscience.com> References: <4CC8461A.1020903@audioscience.com> Message-ID: I took another crack at it. I continued using A-Synchronized transfers with a single burst. When transfer length does not fit in the 16 bits, it will use the CCNT with a BCNT of 32K. So it is still unable to do transfers of 64K or more which are not multiples of 32K. Possible solutions I can see: 1) Try to find a dynamic size of BCNT that would work instead of 32K. This would not fix all cases. I figure it would make the code harder to read also. 2) Allocate a buffer which will let us use a single PaRAM slot. A single buffer can be use by setting BCNTRLD to 32K and setting the initial BCNT to the leftover size. For this to work, we need a larger buffer padded to 32K where there would be a gap after the initial frame. This is because we have to work around the CIDX. 3) Use 2 linked PaRAM slot. One slot would be used for multiples of 32K while the other would be used for the leftover. Please correct me if I am wrong. Here is my patch diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 5c9e9ce..93e716d 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -763,27 +763,47 @@ static int davinci_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count, DMA_FROM_DEVICE); - tx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_tx_channel); - tx_param.src = t->tx_buf ? t->tx_dma : tx_reg; - tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; - tx_param.dst = tx_reg; - tx_param.src_dst_bidx = t->tx_buf ? data_type : 0; - tx_param.link_bcntrld = 0xffff; - tx_param.src_dst_cidx = 0; - tx_param.ccnt = 1; - edma_write_slot(davinci_dma->dma_tx_channel, &tx_param); - edma_link(davinci_dma->dma_tx_channel, - davinci_dma->dummy_param_slot); - - rx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_rx_channel); - rx_param.src = rx_reg; - rx_param.a_b_cnt = davinci_spi->rcount << 16 | data_type; - rx_param.dst = t->rx_dma; - rx_param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; - rx_param.link_bcntrld = 0xffff; - rx_param.src_dst_cidx = 0; - rx_param.ccnt = 1; - edma_write_slot(davinci_dma->dma_rx_channel, &rx_param); + if( davinci_spi->wcount < 0x10000 || !(davinci_spi->wcount & 0x7fff) ) { + /*We can use a single PaRAM slot*/ + tx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_tx_channel); + tx_param.src = t->tx_buf ? t->tx_dma : tx_reg; + tx_param.dst = tx_reg; + tx_param.src_dst_bidx = t->tx_buf ? data_type : 0; + tx_param.src_dst_cidx = t->tx_buf ? data_type : 0; + tx_param.link_bcntrld = (0x8000 << 16) | 0xffff; + if( davinci_spi->wcount < 0x10000 ) { /*Use a single frame of BCNT=wcount*/ + tx_param.a_b_cnt = davinci_spi->wcount << 16 | data_type; + tx_param.ccnt = 1; + } + else { /*Use multiple frames of BCNT=32K*/ + tx_param.a_b_cnt = 0x8000 << 16 | data_type; + tx_param.ccnt = davinci_spi->wcount / 0x8000; + } + edma_write_slot(davinci_dma->dma_tx_channel, &tx_param); + edma_link(davinci_dma->dma_tx_channel, + davinci_dma->dummy_param_slot); + + rx_param.opt = TCINTEN | EDMA_TCC(davinci_dma->dma_rx_channel); + rx_param.src = rx_reg; + rx_param.dst = t->rx_dma; + rx_param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16; + rx_param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16; + rx_param.link_bcntrld = (0x8000 << 16) | 0xffff; + if( davinci_spi->rcount < 0x10000 ) { /*Use a single frame of BCNT=wcount*/ + rx_param.a_b_cnt = davinci_spi->rcount << 16 | data_type; + rx_param.ccnt = 1; + } + else { /*Use multiple frames of BCNT=32K*/ + rx_param.a_b_cnt = 0x8000 << 16 | data_type; + rx_param.ccnt = davinci_spi->rcount / 0x8000; + } + edma_write_slot(davinci_dma->dma_rx_channel, &rx_param); + } + else { + /*Need to use multiple PaRAM slots*/ + printk("unsupported\n"); + return -EIO; + } iowrite16(spidat1 >> SPIDAT1_CSNR_SHIFT, davinci_spi->base + SPIDAT1 + 2); From vm.rod25 at gmail.com Fri Oct 29 10:10:45 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:45 -0500 Subject: [PATCH v6 9/9] davinci: USB1.1 support for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-10-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule Device Drivers ---> SCSI device support ---> SCSI device support legacy /proc/scsi/ support SCSI disk support SCSI low-level drivers USB support ---> Support for Host-side US OHCI HCD support (NEW) USB Mass Storage support (NEW) USB Gadget Support ---> USB Gadget Drivers (Ethernet Gadget\ (with CDC Ethernet support)) ---> NOP USB Transceiver Driver And you will be able to mount and USB pen drive In order to connect a keyboard or a mouse on a USB-hub select in menuconfig like insmodule HID Devices ---> Generic HID support USB Human Interface Device (full HID) support arch/arm/mach-davinci/board-omapl138-hawk.c | 107 +++++++++++++++++++++++++++ 1 files changed, 107 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 02e54fa..5c8202b 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -26,6 +26,9 @@ #define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) #define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) +#define DA850_USB1_VBUS_PIN GPIO_TO_PIN(2, 4) +#define DA850_USB1_OC_PIN GPIO_TO_PIN(6, 13) + static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, @@ -204,6 +207,108 @@ static __init void omapl138_hawk_mmc_init(void) __func__, ret); } +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id); +static da8xx_ocic_handler_t hawk_usb_ocic_handler; + +static const short da850_hawk_usb11_pins[] = { + DA850_GPIO2_4, DA850_GPIO6_13, + -1 +}; + +static int hawk_usb_set_power(unsigned port, int on) +{ + gpio_set_value(DA850_USB1_VBUS_PIN, on); + return 0; +} + +static int hawk_usb_get_power(unsigned port) +{ + return gpio_get_value(DA850_USB1_VBUS_PIN); +} + +static int hawk_usb_get_oci(unsigned port) +{ + return !gpio_get_value(DA850_USB1_OC_PIN); +} + +static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) +{ + int irq = gpio_to_irq(DA850_USB1_OC_PIN); + int error = 0; + + if (handler != NULL) { + hawk_usb_ocic_handler = handler; + + error = request_irq(irq, omapl138_hawk_usb_ocic_irq, + IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + "OHCI over-current indicator", NULL); + if (error) + pr_err(KERN_ERR "%s: could not request IRQ to watch " + "over-current indicator changes\n", __func__); + } else + free_irq(irq, NULL); + + return error; +} + +static struct da8xx_ohci_root_hub omapl138_hawk_usb11_pdata = { + .set_power = hawk_usb_set_power, + .get_power = hawk_usb_get_power, + .get_oci = hawk_usb_get_oci, + .ocic_notify = hawk_usb_ocic_notify, + /* TPS2087 switch @ 5V */ + .potpgt = (3 + 1) / 2, /* 3 ms max */ +}; + +static irqreturn_t omapl138_hawk_usb_ocic_irq(int irq, void *dev_id) +{ + hawk_usb_ocic_handler(&omapl138_hawk_usb11_pdata, 1); + return IRQ_HANDLED; +} + +static __init void omapl138_hawk_usb_init(void) +{ + int ret; + u32 cfgchip2; + + ret = davinci_cfg_reg_list(da850_hawk_usb11_pins); + if (ret) { + pr_warning("%s: USB 1.1 PinMux setup failed: %d\n", + __func__, ret); + return; + } + + /* + * Setup the Ref. clock frequency for the HAWK at 24 MHz. + */ + cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + cfgchip2 &= ~CFGCHIP2_REFFREQ; + cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; + __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); + + ret = gpio_request_one(DA850_USB1_VBUS_PIN, + GPIOF_DIR_OUT, "USB1 VBUS"); + if (ret < 0) { + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "power control: %d\n", __func__, ret); + return; + } + + ret = gpio_request_one(DA850_USB1_OC_PIN, + GPIOF_DIR_IN, "USB1 OC"); + if (ret < 0) { + pr_err(KERN_ERR "%s: failed to request GPIO for USB 1.1 port " + "over-current indicator: %d\n", __func__, ret); + return; + } + + ret = da8xx_register_usb11(&omapl138_hawk_usb11_pdata); + if (ret) + pr_warning("%s: USB 1.1 registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -236,6 +341,8 @@ static __init void omapl138_hawk_init(void) omapl138_hawk_mmc_init(); + omapl138_hawk_usb_init(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:36 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:36 -0500 Subject: [PATCH v6 0/9] Add Omapl138-Hawkboard support Message-ID: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC, EDMA, ASoC, SOUND, MMC/SD and USB OHCI support for the Hawkboard-L138 system It is under the machine name "omapl138_hawkboard". This system is based on the da850 davinci CPU architecture. Victor Rodriguez (9): davinci: EMAC support for Omapl138-Hawkboard davinci: EDMA support for Omapl138-Hawkboard davinci: ASoC support for Omapl138-Hawkboard davinci: McASP configuration for Omapl138-Hawkboard davinci: Audio support for Omapl138-Hawkboard davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard davinci: MMC/SD support for Omapl138-Hawkboar davinci: USB clocks for Omapl138-Hawkboard davinci: USB1.1 support for Omapl138-Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 313 +++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 22 ++- arch/arm/mach-davinci/include/mach/mux.h | 4 + sound/soc/davinci/Kconfig | 5 +- sound/soc/davinci/davinci-evm.c | 6 +- 5 files changed, 345 insertions(+), 5 deletions(-) From vm.rod25 at gmail.com Fri Oct 29 10:10:42 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:42 -0500 Subject: [PATCH v6 6/9] davinci: MMC/SD and USB-OHCI configuration for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-7-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration to enable MMC/SD and USB-OHCI on the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 4 ++++ arch/arm/mach-davinci/include/mach/mux.h | 4 ++++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index f033a0a..4458bff 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -543,11 +543,15 @@ static const struct mux_config da850_pins[] = { MUX_CFG(DA850, EMA_WAIT_1, 6, 24, 15, 1, false) MUX_CFG(DA850, NEMA_CS_2, 7, 0, 15, 1, false) /* GPIO function */ + MUX_CFG(DA850, GPIO2_4, 6, 12, 15, 8, false) MUX_CFG(DA850, GPIO2_6, 6, 4, 15, 8, false) MUX_CFG(DA850, GPIO2_8, 5, 28, 15, 8, false) MUX_CFG(DA850, GPIO2_15, 5, 0, 15, 8, false) + MUX_CFG(DA850, GPIO3_12, 7, 12, 15, 8, false) + MUX_CFG(DA850, GPIO3_13, 7, 8, 15, 8, false) MUX_CFG(DA850, GPIO4_0, 10, 28, 15, 8, false) MUX_CFG(DA850, GPIO4_1, 10, 24, 15, 8, false) + MUX_CFG(DA850, GPIO6_13, 13, 8, 15, 8, false) MUX_CFG(DA850, RTC_ALARM, 0, 28, 15, 2, false) #endif }; diff --git a/arch/arm/mach-davinci/include/mach/mux.h b/arch/arm/mach-davinci/include/mach/mux.h index de11aac..5d4e0fe 100644 --- a/arch/arm/mach-davinci/include/mach/mux.h +++ b/arch/arm/mach-davinci/include/mach/mux.h @@ -908,11 +908,15 @@ enum davinci_da850_index { DA850_NEMA_CS_2, /* GPIO function */ + DA850_GPIO2_4, DA850_GPIO2_6, DA850_GPIO2_8, DA850_GPIO2_15, + DA850_GPIO3_12, + DA850_GPIO3_13, DA850_GPIO4_0, DA850_GPIO4_1, + DA850_GPIO6_13, DA850_RTC_ALARM, }; -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:44 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:44 -0500 Subject: [PATCH v6 8/9] davinci: USB clocks for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-9-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds USB1.1 and USB2.0 clocks for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 4458bff..b3b1adb 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -345,6 +345,20 @@ static struct clk aemif_clk = { .flags = ALWAYS_ENABLED, }; +static struct clk usb11_clk = { + .name = "usb11", + .parent = &pll0_sysclk4, + .lpsc = DA8XX_LPSC1_USB11, + .gpsc = 1, +}; + +static struct clk usb20_clk = { + .name = "usb20", + .parent = &pll0_sysclk2, + .lpsc = DA8XX_LPSC1_USB20, + .gpsc = 1, +}; + static struct clk_lookup da850_clks[] = { CLK(NULL, "ref", &ref_clk), CLK(NULL, "pll0", &pll0_clk), @@ -387,6 +401,8 @@ static struct clk_lookup da850_clks[] = { CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK(NULL, "aemif", &aemif_clk), + CLK(NULL, "usb11", &usb11_clk), + CLK(NULL, "usb20", &usb20_clk), CLK(NULL, NULL, NULL), }; -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:43 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:43 -0500 Subject: [PATCH v6 7/9] davinci: MMC/SD support for Omapl138-Hawkboar In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-8-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds MMC/SD support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test it select in menuconfig like insmodule MMC/SD/SDIO card support ---> MMC block device driver Use bounce buffer for simple hosts TI DAVINCI Multimedia Card Interface support arch/arm/mach-davinci/board-omapl138-hawk.c | 63 +++++++++++++++++++++++++++ 1 files changed, 63 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 115dac0..02e54fa 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -23,6 +23,8 @@ #include #define HAWKBOARD_PHY_ID "0:07" +#define DA850_HAWK_MMCSD_CD_PIN GPIO_TO_PIN(3, 12) +#define DA850_HAWK_MMCSD_WP_PIN GPIO_TO_PIN(3, 13) static short omapl138_hawk_mii_pins[] __initdata = { DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, @@ -143,6 +145,65 @@ static struct snd_platform_data omapl138_hawk_snd_data = { .rxnumevt = 1, }; +static const short hawk_mmcsd0_pins[] = { + DA850_MMCSD0_DAT_0, DA850_MMCSD0_DAT_1, DA850_MMCSD0_DAT_2, + DA850_MMCSD0_DAT_3, DA850_MMCSD0_CLK, DA850_MMCSD0_CMD, + DA850_GPIO3_12, DA850_GPIO3_13, + -1 +}; + +static int da850_hawk_mmc_get_ro(int index) +{ + return gpio_get_value(DA850_HAWK_MMCSD_WP_PIN); +} + +static int da850_hawk_mmc_get_cd(int index) +{ + return !gpio_get_value(DA850_HAWK_MMCSD_CD_PIN); +} + +static struct davinci_mmc_config da850_mmc_config = { + .get_ro = da850_hawk_mmc_get_ro, + .get_cd = da850_hawk_mmc_get_cd, + .wires = 4, + .max_freq = 50000000, + .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED, + .version = MMC_CTLR_VERSION_2, +}; + +static __init void omapl138_hawk_mmc_init(void) +{ + int ret; + + ret = davinci_cfg_reg_list(hawk_mmcsd0_pins); + if (ret) { + pr_warning("%s: MMC/SD0 mux setup failed: %d\n", + __func__, ret); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_CD_PIN, + GPIOF_DIR_IN, "MMC CD"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_CD_PIN); + return; + } + + ret = gpio_request_one(DA850_HAWK_MMCSD_WP_PIN, + GPIOF_DIR_IN, "MMC WP"); + if (ret < 0) { + pr_warning("%s: can not open GPIO %d\n", + __func__, DA850_HAWK_MMCSD_WP_PIN); + return; + } + + ret = da8xx_register_mmcsd0(&da850_mmc_config); + if (ret) + pr_warning("%s: MMC/SD0 registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -173,6 +234,8 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + omapl138_hawk_mmc_init(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:40 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:40 -0500 Subject: [PATCH v6 4/9] davinci: McASP configuration for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-5-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch defines Pin Mux configuration for MacASP used on the Hawkboard-L138 system in order to add Audio support Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/da850.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index 63916b9..f033a0a 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -591,7 +591,7 @@ const short da850_cpgmac_pins[] __initdata = { const short da850_mcasp_pins[] __initdata = { DA850_AHCLKX, DA850_ACLKX, DA850_AFSX, DA850_AHCLKR, DA850_ACLKR, DA850_AFSR, DA850_AMUTE, - DA850_AXR_11, DA850_AXR_12, + DA850_AXR_11, DA850_AXR_12, DA850_AXR_13, DA850_AXR_14, -1 }; -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:37 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:37 -0500 Subject: [PATCH v6 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-2-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EMAC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 43 +++++++++++++++++++++++++++ 1 files changed, 43 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index c472dd8..62d35f0 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -19,6 +19,47 @@ #include #include +#include + +#define HAWKBOARD_PHY_ID "0:07" + +static short omapl138_hawk_mii_pins[] __initdata = { + DA850_MII_TXEN, DA850_MII_TXCLK, DA850_MII_COL, DA850_MII_TXD_3, + DA850_MII_TXD_2, DA850_MII_TXD_1, DA850_MII_TXD_0, DA850_MII_RXER, + DA850_MII_CRS, DA850_MII_RXCLK, DA850_MII_RXDV, DA850_MII_RXD_3, + DA850_MII_RXD_2, DA850_MII_RXD_1, DA850_MII_RXD_0, DA850_MDIO_CLK, + DA850_MDIO_D, + -1 +}; + +static __init void omapl138_hawk_config_emac(void) +{ + void __iomem *cfgchip3 = DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG); + int ret; + u32 val; + struct davinci_soc_info *soc_info = &davinci_soc_info; + + val = __raw_readl(cfgchip3); + val &= ~BIT(8); + ret = davinci_cfg_reg_list(omapl138_hawk_mii_pins); + if (ret) { + pr_warning("%s: cpgmac/mii mux setup failed: %d\n", + __func__, ret); + return; + } + + /* configure the CFGCHIP3 register for MII */ + __raw_writel(val, cfgchip3); + pr_info("EMAC: MII PHY configured\n"); + + soc_info->emac_pdata->phy_id = HAWKBOARD_PHY_ID; + + ret = da8xx_register_emac(); + if (ret) + pr_warning("%s: emac registration failed: %d\n", + __func__, ret); +} + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -30,6 +71,8 @@ static __init void omapl138_hawk_init(void) davinci_serial_init(&omapl138_hawk_uart_config); + omapl138_hawk_config_emac(); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:41 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:41 -0500 Subject: [PATCH v6 5/9] davinci: Audio support for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-6-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds sound support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- Notes: This patch works with da8xx_omapl_defconfig In order to test ALSA utils select in menuconfig like insmodule: Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support ---> SoC Audio for the TI DAVINCI chip SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard arch/arm/mach-davinci/board-omapl138-hawk.c | 46 +++++++++++++++++++++++++++ 1 files changed, 46 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 114fc9b..115dac0 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -110,6 +111,38 @@ static struct edma_rsv_info *da850_edma_rsv[2] = { &da850_edma_cc1_rsv, }; +static struct i2c_board_info __initdata omapl138_hawk_i2c_devices[] = { + { + I2C_BOARD_INFO("tlv320aic3x", 0x18), + }, +}; + +static struct davinci_i2c_platform_data omapl138_hawk_i2c_0_pdata = { + .bus_freq = 100, /* kHz */ + .bus_delay = 0, /* usec */ +}; + +/* davinci Hawkboard audio machine driver */ +static u8 da850_iis_serializer_direction[] = { + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, INACTIVE_MODE, + INACTIVE_MODE, TX_MODE, RX_MODE, INACTIVE_MODE, +}; + +static struct snd_platform_data omapl138_hawk_snd_data = { + .tx_dma_offset = 0x2000, + .rx_dma_offset = 0x2000, + .op_mode = DAVINCI_MCASP_IIS_MODE, + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, + .asp_chan_q = EVENTQ_1, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +}; + static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, }; @@ -127,6 +160,19 @@ static __init void omapl138_hawk_init(void) pr_warning("%s: EDMA registration failed: %d\n", __func__, ret); + i2c_register_board_info(1, omapl138_hawk_i2c_devices, + ARRAY_SIZE(omapl138_hawk_i2c_devices)); + + ret = da8xx_register_i2c(0, &omapl138_hawk_i2c_0_pdata); + if (ret) + pr_warning("%s: i2c0 registration failed: %d\n", + __func__, ret); + + ret = davinci_cfg_reg_list(da850_mcasp_pins); + if (ret) + pr_warning("%s: mcasp mux setup failed: %d\n", __func__, ret); + da8xx_register_mcasp(0, &omapl138_hawk_snd_data); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:38 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:38 -0500 Subject: [PATCH v6 2/9] davinci: EDMA support for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-3-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds EDMA support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- arch/arm/mach-davinci/board-omapl138-hawk.c | 54 +++++++++++++++++++++++++++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 62d35f0..114fc9b 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -60,6 +60,55 @@ static __init void omapl138_hawk_config_emac(void) __func__, ret); } +/* + * The following EDMA channels/slots are not being used by drivers (for + * example: Timer, GPIO, UART events etc) on da850/omap-l138 EVM/Hawkboard, + * hence they are being reserved for codecs on the DSP side. + */ +static const s16 da850_dma0_rsv_chans[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma0_rsv_slots[][2] = { + /* (offset, number) */ + { 8, 6}, + {24, 4}, + {30, 50}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_chans[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 2}, + {-1, -1} +}; + +static const s16 da850_dma1_rsv_slots[][2] = { + /* (offset, number) */ + { 0, 28}, + {30, 90}, + {-1, -1} +}; + +static struct edma_rsv_info da850_edma_cc0_rsv = { + .rsv_chans = da850_dma0_rsv_chans, + .rsv_slots = da850_dma0_rsv_slots, +}; + +static struct edma_rsv_info da850_edma_cc1_rsv = { + .rsv_chans = da850_dma1_rsv_chans, + .rsv_slots = da850_dma1_rsv_slots, +}; + +static struct edma_rsv_info *da850_edma_rsv[2] = { + &da850_edma_cc0_rsv, + &da850_edma_cc1_rsv, +}; static struct davinci_uart_config omapl138_hawk_uart_config __initdata = { .enabled_uarts = 0x7, @@ -73,6 +122,11 @@ static __init void omapl138_hawk_init(void) omapl138_hawk_config_emac(); + ret = da850_register_edma(da850_edma_rsv); + if (ret) + pr_warning("%s: EDMA registration failed: %d\n", + __func__, ret); + ret = da8xx_register_watchdog(); if (ret) pr_warning("omapl138_hawk_init: " -- 1.7.0.4 From vm.rod25 at gmail.com Fri Oct 29 10:10:39 2010 From: vm.rod25 at gmail.com (vm.rod25 at gmail.com) Date: Fri, 29 Oct 2010 10:10:39 -0500 Subject: [PATCH v6 3/9] davinci: ASoC support for Omapl138-Hawkboard In-Reply-To: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> References: <1288365045-2709-1-git-send-email-vm.rod25@gmail.com> Message-ID: <1288365045-2709-4-git-send-email-vm.rod25@gmail.com> From: Victor Rodriguez This patch adds ASoC support for the Hawkboard-L138 system Signed-off-by: Victor Rodriguez --- sound/soc/davinci/Kconfig | 5 +++-- sound/soc/davinci/davinci-evm.c | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index 6bbf001..72c6752 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig @@ -76,8 +76,9 @@ config SND_DA830_SOC_EVM DA830/OMAP-L137 EVM config SND_DA850_SOC_EVM - tristate "SoC Audio support for DA850/OMAP-L138 EVM" - depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM + tristate "SoC Audio support for DA850/OMAP-L138 EVM/Hawkboard" + depends on SND_DAVINCI_SOC && (MACH_DAVINCI_DA850_EVM || \ + MACH_OMAPL138_HAWKBOARD) select SND_DAVINCI_SOC_MCASP select SND_SOC_TLV320AIC3X help diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 97f74d6..73093eb 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -59,7 +59,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream, sysclk = 12288000; else if (machine_is_davinci_da830_evm() || - machine_is_davinci_da850_evm()) + machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) sysclk = 24576000; else @@ -311,7 +312,8 @@ static int __init evm_init(void) } else if (machine_is_davinci_da830_evm()) { evm_snd_dev_data = &da830_evm_snd_devdata; index = 1; - } else if (machine_is_davinci_da850_evm()) { + } else if (machine_is_davinci_da850_evm() || + machine_is_omapl138_hawkboard()) { evm_snd_dev_data = &da850_evm_snd_devdata; index = 0; } else -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:16 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:16 -0400 Subject: [PATCH v4 00/12] tnetv107x ssp driver stack Message-ID: <1288124308-14999-1-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch series implements a driver stack that looks like the following: +--------+ | eeprom | . . . +--------+ +-----------+ +--------------+ +---------+ | regulator | . . . | i2c-gpio | | 1-wire | . . . +-----------+ +--------------+ +---------+ +----------------------+ +--------------------------------+ | ssp-spi | | ssp-gpio | +----------------------+ +--------------------------------+ +----------------------------------------------------------+ | ssp | +----------------------------------------------------------+ Changes between v3 and v4 of this series: - Replaced polled wait for sequence termination with interrupt - Improved locking within SSP driver - Other minor cleanups Changes between v2 and v3 of this series: - Minor cleanups in Kconfig and Makefile ordering Changes between v1 and v2 of this series: - Replaced open()/close() semantics with dynamic platform_device registration on SSP probe. - Removed user-land interface to regulator registers - More sensible regulator constraints - Other minor cleanups Cyril Chemparathy (12): misc: add driver for sequencer serial port davinci: add tnetv107x ssp platform device davinci: add ssp config for tnetv107x evm board spi: add ti-ssp spi master driver davinci: add spi devices on tnetv107x evm regulator: add driver for tps6524x regulator davinci: add tnetv107x evm regulators gpio: add ti-ssp gpio driver davinci: add tnetv107x evm ti-ssp gpio device backlight: add support for tps6116x controller davinci: add tnetv107x evm backlight device davinci: add tnetv107x evm i2c eeprom device arch/arm/mach-davinci/board-tnetv107x-evm.c | 199 +++++++ arch/arm/mach-davinci/devices-tnetv107x.c | 25 + arch/arm/mach-davinci/include/mach/ti_ssp.h | 98 ++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- drivers/gpio/Kconfig | 10 + drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++ drivers/misc/Kconfig | 10 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 492 +++++++++++++++++ drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++ drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 396 ++++++++++++++ drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++ 20 files changed, 2494 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/gpio/ti-ssp-gpio.c create mode 100644 drivers/misc/ti_ssp.c create mode 100644 drivers/regulator/tps6524x-regulator.c create mode 100644 drivers/spi/spi_ti_ssp.c create mode 100644 drivers/video/backlight/tps6116x.c From cyril at ti.com Tue Oct 26 15:18:17 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:17 -0400 Subject: [PATCH v4 01/12] misc: add driver for sequencer serial port In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-2-git-send-email-cyril@ti.com> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port device. It has a built-in programmable execution engine that can be programmed to operate as almost any serial bus (I2C, SPI, EasyScale, and others). This patch adds a driver for this controller device. The driver does not expose a user-land interface. Protocol drivers built on top of this layer are expected to remain in-kernel. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 89 +++++ drivers/misc/Kconfig | 10 + drivers/misc/Makefile | 1 + drivers/misc/ti_ssp.c | 492 +++++++++++++++++++++++++++ 4 files changed, 592 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-davinci/include/mach/ti_ssp.h create mode 100644 drivers/misc/ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h new file mode 100644 index 0000000..c98d0f2 --- /dev/null +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -0,0 +1,89 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __TI_SSP_H__ +#define __TI_SSP_H__ + +struct ti_ssp_dev_data { + const char *dev_name; + unsigned long iosel; /* see note below */ + unsigned long config; + const void *pdata; + size_t pdata_size; +}; + +struct ti_ssp_data { + unsigned long out_clock; + struct ti_ssp_dev_data dev_data[2]; +}; + +/* + * Sequencer port IO pin configuration bits. These do not correlate 1-1 with + * the hardware. The iosel field in the port data combines iosel1 and iosel2, + * and is therefore not a direct map to register space. It is best to use the + * macros below to construct iosel values. + * + * least significant 16 bits --> iosel1 + * most significant 16 bits --> iosel2 + */ + +#define SSP_IN 0x0000 +#define SSP_DATA 0x0001 +#define SSP_CLOCK 0x0002 +#define SSP_CHIPSEL 0x0003 +#define SSP_OUT 0x0004 +#define SSP_PIN_SEL(pin, v) ((v) << ((pin) * 3)) +#define SSP_PIN_MASK(pin) SSP_PIN_SEL(pin, 0x7) +#define SSP_INPUT_SEL(pin) ((pin) << 16) + +/* Sequencer port config bits */ +#define SSP_EARLY_DIN BIT(8) +#define SSP_DELAY_DOUT BIT(9) + +/* Sequence map definitions */ +#define SSP_CLK_HIGH BIT(0) +#define SSP_CLK_LOW 0 +#define SSP_DATA_HIGH BIT(1) +#define SSP_DATA_LOW 0 +#define SSP_CS_HIGH BIT(2) +#define SSP_CS_LOW 0 +#define SSP_OUT_MODE BIT(3) +#define SSP_IN_MODE 0 +#define SSP_DATA_REG BIT(4) +#define SSP_ADDR_REG 0 + +#define SSP_OPCODE_DIRECT ((0x0) << 5) +#define SSP_OPCODE_TOGGLE ((0x1) << 5) +#define SSP_OPCODE_SHIFT ((0x2) << 5) +#define SSP_OPCODE_BRANCH0 ((0x4) << 5) +#define SSP_OPCODE_BRANCH1 ((0x5) << 5) +#define SSP_OPCODE_BRANCH ((0x6) << 5) +#define SSP_OPCODE_STOP ((0x7) << 5) +#define SSP_BRANCH(addr) ((addr) << 8) +#define SSP_COUNT(cycles) ((cycles) << 8) + +int ti_ssp_raw_read(struct device *dev); +int ti_ssp_raw_write(struct device *dev, u32 val); +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len); +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output); +int ti_ssp_set_mode(struct device *dev, int mode); +int ti_ssp_set_iosel(struct device *dev, u32 iosel); + +#endif /* __TI_SSP_H__ */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index b743312..a8b7ce3 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -390,6 +390,16 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. +config TI_SSP + tristate "Sequencer Serial Port support" + depends on ARCH_DAVINCI_TNETV107X + ---help--- + Say Y here if you want support for the Sequencer Serial Port + in a Texas Instruments TNETV107X SoC. + + To compile this driver as a module, choose M here: the + module will be called ti_ssp. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 42eab95..7568100 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o obj-$(CONFIG_DS1682) += ds1682.o obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o +obj-$(CONFIG_TI_SSP) += ti_ssp.o obj-$(CONFIG_C2PORT) += c2port/ obj-$(CONFIG_IWMC3200TOP) += iwmc3200top/ obj-$(CONFIG_HMC6352) += hmc6352.o diff --git a/drivers/misc/ti_ssp.c b/drivers/misc/ti_ssp.c new file mode 100644 index 0000000..5d9dc23 --- /dev/null +++ b/drivers/misc/ti_ssp.c @@ -0,0 +1,492 @@ +/* + * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Register Offsets */ +#define REG_REV 0x00 +#define REG_IOSEL_1 0x04 +#define REG_IOSEL_2 0x08 +#define REG_PREDIV 0x0c +#define REG_INTR_ST 0x10 +#define REG_INTR_EN 0x14 +#define REG_TEST_CTRL 0x18 + +/* Per port registers */ +#define PORT_CFG_2 0x00 +#define PORT_ADDR 0x04 +#define PORT_DATA 0x08 +#define PORT_CFG_1 0x0c +#define PORT_STATE 0x10 + +#define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) +#define SSP_PORT_CLKRATE_MASK 0x0f + +#define SSP_SEQRAM_WR_EN BIT(4) +#define SSP_SEQRAM_RD_EN BIT(5) +#define SSP_START BIT(15) +#define SSP_BUSY BIT(10) +#define SSP_PORT_ASL BIT(7) +#define SSP_PORT_CFO1 BIT(6) + +#define SSP_PORT_SEQRAM_SIZE 32 + +static const int ssp_port_base[] = {0x040, 0x080}; +static const int ssp_port_seqram[] = {0x100, 0x180}; + +struct ti_ssp { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; + struct clk *clk; + int irq; + const struct ti_ssp_data *data; + wait_queue_head_t wqh; +}; + +static inline struct ti_ssp *dev_to_ssp(struct device *dev) +{ + return dev_get_drvdata(dev->parent); +} + +static inline int dev_to_port(struct device *dev) +{ + return to_platform_device(dev)->id; +} + +/* Register Access Helpers, rmw() functions need to run locked */ +static inline u32 ssp_read(struct ti_ssp *ssp, int reg) +{ + return __raw_readl(ssp->regs + reg); +} + +static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) +{ + __raw_writel(val, ssp->regs + reg); +} + +static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) +{ + u32 val = ssp_read(ssp, reg); + val &= ~mask; + val |= bits; + ssp_write(ssp, reg, val); +} + +static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg) +{ + return ssp_read(ssp, ssp_port_base[port] + reg); +} + +static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg, + u32 val) +{ + ssp_write(ssp, ssp_port_base[port] + reg, val); +} + +static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg, + u32 mask, u32 bits) +{ + ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits); +} + +static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, bits, 0); +} + +static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg, + u32 bits) +{ + ssp_port_rmw(ssp, port, reg, 0, bits); +} + +/* Called to setup port clock mode, caller must hold ssp->lock */ +static int __set_mode(struct ti_ssp *ssp, int port, int mode) +{ + mode &= SSP_PORT_CONFIG_MASK; + ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode); + + return 0; +} + +int ti_ssp_set_mode(struct device *dev, int mode) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_mode(ssp, port, mode); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_mode); + +/* Called to setup port iosel, caller must hold ssp->lock */ +static int __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) +{ + unsigned val; + + /* IOSEL1 gets the least significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_1); + val &= 0xffff << (port ? 0 : 16); + val |= (iosel & 0xffff) << (port ? 16 : 0); + ssp_write(ssp, REG_IOSEL_1, val); + + /* IOSEL2 gets the most significant 16 bits */ + val = ssp_read(ssp, REG_IOSEL_2); + val &= 0x0007 << (port ? 0 : 16); + val |= (iosel & 0x00070000) >> (port ? 0 : 16); + ssp_write(ssp, REG_IOSEL_2, val); + + return 0; +} + +int ti_ssp_set_iosel(struct device *dev, u32 iosel) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + int ret; + + spin_lock(&ssp->lock); + ret = __set_iosel(ssp, port, iosel); + spin_unlock(&ssp->lock); + + return ret; +} +EXPORT_SYMBOL(ti_ssp_set_iosel); + +int ti_ssp_load(struct device *dev, int offs, u32* prog, int len) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + int i; + + if (len > SSP_PORT_SEQRAM_SIZE) + return -ENOSPC; + + spin_lock(&ssp->lock); + + /* Enable SeqRAM access */ + ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + /* Copy code */ + for (i = 0; i < len; i++) { + __raw_writel(prog[i], ssp->regs + offs + 4*i + + ssp_port_seqram[port]); + } + + /* Disable SeqRAM access */ + ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); + + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_load); + +int ti_ssp_raw_read(struct device *dev) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + u32 val; + + val = ssp_read(ssp, REG_IOSEL_2); + val >>= (port ? 27 : 11); + + return val & 0x0f; +} +EXPORT_SYMBOL(ti_ssp_raw_read); + +int ti_ssp_raw_write(struct device *dev, u32 val) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + u32 mask; + + spin_lock(&ssp->lock); + + val &= 0x0f; + val <<= (port ? 22 : 6); + mask = 0x0f << (port ? 22 : 6); + ssp_rmw(ssp, REG_IOSEL_2, mask, val); + + spin_unlock(&ssp->lock); + + return 0; +} +EXPORT_SYMBOL(ti_ssp_raw_write); + +static inline int __xfer_done(struct ti_ssp *ssp, int port) +{ + return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY); +} + +int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) +{ + struct ti_ssp *ssp = dev_to_ssp(dev); + int port = dev_to_port(dev); + int ret; + + if (pc & ~(0x3f)) + return -EINVAL; + + /* Grab ssp->lock to serialize rmw on ssp registers */ + spin_lock(&ssp->lock); + + ssp_port_write(ssp, port, PORT_ADDR, input >> 16); + ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); + ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); + + /* grab wait queue head lock to avoid race with the isr */ + spin_lock_irq(&ssp->wqh.lock); + + /* kick off sequence execution in hardware */ + ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); + + /* drop ssp lock; no register writes beyond this */ + spin_unlock(&ssp->lock); + + ret = wait_event_interruptible_locked_irq(ssp->wqh, + __xfer_done(ssp, port)); + spin_unlock_irq(&ssp->wqh.lock); + + if (ret < 0) + return ret; + + if (output) { + *output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | + (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); + } + + ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */ + + return ret; +} +EXPORT_SYMBOL(ti_ssp_run); + +static irqreturn_t ti_ssp_interrupt(int irq, void *data) +{ + struct ti_ssp *ssp = data; + + spin_lock(&ssp->wqh.lock); + + ssp_write(ssp, REG_INTR_ST, 0x3); + wake_up_locked(&ssp->wqh); + + spin_unlock(&ssp->wqh.lock); + + return IRQ_HANDLED; +} + +static int __unregister_subdev(struct device *dev, void *unused) +{ + platform_device_unregister(to_platform_device(dev)); + return 0; +} + +static int unregister_subdevs(struct ti_ssp *ssp) +{ + return device_for_each_child(ssp->dev, NULL, __unregister_subdev); +} + +static void register_subdevs(struct ti_ssp *ssp) +{ + int id; + + for (id = 0; id < 2; id++) { + const struct ti_ssp_dev_data *data = &ssp->data->dev_data[id]; + + if (!data->dev_name) + continue; + + spin_lock(&ssp->lock); + __set_iosel(ssp, id, data->iosel); + ssp_port_rmw(ssp, id, PORT_CFG_1, SSP_PORT_CONFIG_MASK, + data->config); + ssp_port_rmw(ssp, id, PORT_CFG_2, SSP_PORT_CLKRATE_MASK, 0); + spin_unlock(&ssp->lock); + + platform_device_register_data(ssp->dev, data->dev_name, id, + data->pdata, data->pdata_size); + } +} + +static int __devinit ti_ssp_probe(struct platform_device *pdev) +{ + static struct ti_ssp *ssp; + const struct ti_ssp_data *pdata = pdev->dev.platform_data; + int ret = 0, prediv = 0xff; + unsigned long sysclk; + struct device *dev = &pdev->dev; + + ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); + if (!ssp) { + dev_err(dev, "cannot allocate device info\n"); + return -ENOMEM; + } + + ssp->data = pdata; + ssp->dev = dev; + dev_set_drvdata(dev, ssp); + + ret = -ENODEV; + ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!ssp->res) { + dev_err(dev, "cannot determine register area\n"); + goto error_res; + } + + ret = -EINVAL; + if (!request_mem_region(ssp->res->start, resource_size(ssp->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + goto error_res; + } + + ret = -ENOMEM; + ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); + if (!ssp->regs) { + dev_err(dev, "cannot map register memory\n"); + goto error_map; + } + + ret = -EINVAL; + ssp->clk = clk_get(dev, NULL); + if (IS_ERR(ssp->clk)) { + dev_err(dev, "cannot claim device clock\n"); + goto error_clk; + } + + ssp->irq = platform_get_irq(pdev, 0); + if (ssp->irq < 0) { + dev_err(dev, "unknown irq\n"); + goto error_irq; + } + + ret = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0, + dev_name(dev), ssp); + if (ret < 0) { + dev_err(dev, "cannot acquire irq\n"); + goto error_irq; + } + + spin_lock_init(&ssp->lock); + init_waitqueue_head(&ssp->wqh); + + /* Power on and initialize SSP */ + ret = clk_enable(ssp->clk); + if (ret) + goto error_enable; + + /* Reset registers to a sensible known state */ + ssp_write(ssp, REG_IOSEL_1, 0); + ssp_write(ssp, REG_IOSEL_2, 0); + ssp_write(ssp, REG_INTR_EN, 0x3); + ssp_write(ssp, REG_INTR_ST, 0x3); + ssp_write(ssp, REG_TEST_CTRL, 0); + ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL); + ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1); + ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1); + + sysclk = clk_get_rate(ssp->clk); + if (pdata && pdata->out_clock) + prediv = (sysclk / pdata->out_clock) - 1; + prediv = clamp(prediv, 0, 0xff); + ssp_rmw(ssp, REG_PREDIV, 0xff, prediv); + + register_subdevs(ssp); + + return 0; + +error_enable: + free_irq(ssp->irq, ssp); +error_irq: + clk_put(ssp->clk); +error_clk: + iounmap(ssp->regs); +error_map: + release_mem_region(ssp->res->start, resource_size(ssp->res)); +error_res: + kfree(ssp); + return ret; +} + +static int __devexit ti_ssp_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ti_ssp *ssp = dev_get_drvdata(dev); + + unregister_subdevs(ssp); + clk_disable(ssp->clk); + free_irq(ssp->irq, ssp); + clk_put(ssp->clk); + iounmap(ssp->regs); + release_mem_region(ssp->res->start, resource_size(ssp->res)); + kfree(ssp); + dev_set_drvdata(dev, NULL); + return 0; +} + +static struct platform_driver ti_ssp_driver = { + .probe = ti_ssp_probe, + .remove = __devexit_p(ti_ssp_remove), + .driver = { + .name = "ti-ssp", + .owner = THIS_MODULE, + } +}; + +static int __init ti_ssp_init(void) +{ + return platform_driver_register(&ti_ssp_driver); +} +arch_initcall_sync(ti_ssp_init); + +static void __exit ti_ssp_exit(void) +{ + platform_driver_unregister(&ti_ssp_driver); +} +module_exit(ti_ssp_exit); + +MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti_ssp"); -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:19 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:19 -0400 Subject: [PATCH v4 03/12] davinci: add ssp config for tnetv107x evm board In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-4-git-send-email-cyril@ti.com> This patch adds SSP configuration and pin muxing info for tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index a6db854..c74ea66 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define EVM_MMC_WP_GPIO 21 @@ -99,6 +100,12 @@ static const short uart1_pins[] __initdata = { -1 }; +static const short ssp_pins[] __initdata = { + TNETV107X_SSP0_0, TNETV107X_SSP0_1, TNETV107X_SSP0_2, + TNETV107X_SSP1_0, TNETV107X_SSP1_1, TNETV107X_SSP1_2, + TNETV107X_SSP1_3, -1 +}; + static struct mtd_partition nand_partitions[] = { /* bootloader (U-Boot, etc) in first 12 sectors */ { @@ -196,17 +203,25 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static struct ti_ssp_data ssp_config = { + .out_clock = 250 * 1000, + .dev_data = { + }, +}; + static struct tnetv107x_device_info evm_device_info __initconst = { .serial_config = &serial_config, .mmc_config[1] = &mmc_config, /* controller 1 */ .nand_config[0] = &nand_config, /* chip select 0 */ .keypad_config = &keypad_config, + .ssp_config = &ssp_config, }; static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); davinci_cfg_reg_list(uart1_pins); + davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); } -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:18 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:18 -0400 Subject: [PATCH v4 02/12] davinci: add tnetv107x ssp platform device In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-3-git-send-email-cyril@ti.com> This patch adds an SSP platform device definition for the tnetv107x soc family. The clock lookup entry has also been updated to match. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/devices-tnetv107x.c | 25 ++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/tnetv107x.h | 2 + arch/arm/mach-davinci/tnetv107x.c | 2 +- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 85503de..6162cae 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm/mach-davinci/devices-tnetv107x.c @@ -35,6 +35,7 @@ #define TNETV107X_SDIO0_BASE 0x08088700 #define TNETV107X_SDIO1_BASE 0x08088800 #define TNETV107X_KEYPAD_BASE 0x08088a00 +#define TNETV107X_SSP_BASE 0x08088c00 #define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000 #define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 #define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000 @@ -342,6 +343,25 @@ static struct platform_device tsc_device = { .resource = tsc_resources, }; +static struct resource ssp_resources[] = { + { + .start = TNETV107X_SSP_BASE, + .end = TNETV107X_SSP_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, + { + .start = IRQ_TNETV107X_SSP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ssp_device = { + .name = "ti-ssp", + .id = -1, + .num_resources = ARRAY_SIZE(ssp_resources), + .resource = ssp_resources, +}; + void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) { int i, error; @@ -380,4 +400,9 @@ void __init tnetv107x_devices_init(struct tnetv107x_device_info *info) keypad_device.dev.platform_data = info->keypad_config; platform_device_register(&keypad_device); } + + if (info->ssp_config) { + ssp_device.dev.platform_data = info->ssp_config; + platform_device_register(&ssp_device); + } } diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h index 5a681d8..c1df563 100644 --- a/arch/arm/mach-davinci/include/mach/tnetv107x.h +++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h @@ -38,12 +38,14 @@ #include #include #include +#include struct tnetv107x_device_info { struct davinci_uart_config *serial_config; struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */ struct matrix_keypad_platform_data *keypad_config; + struct ti_ssp_data *ssp_config; }; extern struct platform_device tnetv107x_wdt_device; diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c index 6fcdece..1b28fdd 100644 --- a/arch/arm/mach-davinci/tnetv107x.c +++ b/arch/arm/mach-davinci/tnetv107x.c @@ -278,7 +278,7 @@ static struct clk_lookup clks[] = { CLK(NULL, "timer1", &clk_timer1), CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm), CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp), - CLK("ti-ssp.0", NULL, &clk_ssp), + CLK("ti-ssp", NULL, &clk_ssp), CLK(NULL, "clk_tdm0", &clk_tdm0), CLK(NULL, "clk_vlynq", &clk_vlynq), CLK(NULL, "clk_mcdma", &clk_mcdma), -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:20 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:20 -0400 Subject: [PATCH v4 04/12] spi: add ti-ssp spi master driver In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-5-git-send-email-cyril@ti.com> This patch adds an SPI master implementation that operates on top of an underlying TI-SSP port. Acked-by: Grant Likely Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 5 + drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi_ti_ssp.c | 396 +++++++++++++++++++++++++++ 4 files changed, 409 insertions(+), 0 deletions(-) create mode 100644 drivers/spi/spi_ti_ssp.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index c98d0f2..bff8ef6 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -34,6 +34,11 @@ struct ti_ssp_data { struct ti_ssp_dev_data dev_data[2]; }; +struct ti_ssp_spi_data { + int num_cs; + void (*select)(int cs); +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7e631fa..37b10e3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -314,6 +314,13 @@ config SPI_STMP3XXX help SPI driver for Freescale STMP37xx/378x SoC SSP interface +config SPI_TI_SSP + tristate "TI SSP Controller SPI Driver" + depends on TI_SSP + help + This selects an SPI master implementation using a TI sequencer + serial port. + config SPI_TXX9 tristate "Toshiba TXx9 SPI controller" depends on GENERIC_GPIO && CPU_TX49XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e9cbd18..a427f3c 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o +obj-$(CONFIG_SPI_TI_SSP) += spi_ti_ssp.o obj-$(CONFIG_SPI_TXX9) += spi_txx9.o obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o diff --git a/drivers/spi/spi_ti_ssp.c b/drivers/spi/spi_ti_ssp.c new file mode 100644 index 0000000..3cb41c5 --- /dev/null +++ b/drivers/spi/spi_ti_ssp.c @@ -0,0 +1,396 @@ +/* + * Sequencer Serial Port (SSP) based SPI master driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define MODE_BITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH) + +struct ti_ssp_spi { + const struct ti_ssp_spi_data *pdata; + struct spi_master *master; + struct device *dev; + spinlock_t lock; + struct list_head msg_queue; + struct completion complete; + int shutdown:1; + struct workqueue_struct *workqueue; + struct work_struct work; + u8 mode, bpw; + int cs_active; + u32 pc_en, pc_dis, pc_wr, pc_rd; +}; + +static u32 do_read_data(struct ti_ssp_spi *hw) +{ + u32 ret; + + ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret); + return ret; +} + +static void do_write_data(struct ti_ssp_spi *hw, u32 data) +{ + ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL); +} + +static int do_transfer(struct ti_ssp_spi *hw, struct spi_message *msg, + struct spi_transfer *t) +{ + int count; + + if (hw->bpw <= 8) { + u8 *rx = t->rx_buf; + const u8 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 1) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else if (hw->bpw <= 16) { + u16 *rx = t->rx_buf; + const u16 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 2) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } else { + u32 *rx = t->rx_buf; + const u32 *tx = t->tx_buf; + + for (count = 0; count < t->len; count += 4) { + if (t->tx_buf) + do_write_data(hw, *tx++); + if (t->rx_buf) + *rx++ = do_read_data(hw); + } + } + + msg->actual_length += count; /* bytes transferred */ + + dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n", + t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len, + hw->bpw, count, (count < t->len) ? " (under)" : ""); + + return (count < t->len) ? -EIO : 0; /* left over data */ +} + +static void chip_select(struct ti_ssp_spi *hw, int cs_active) +{ + cs_active = !!cs_active; + if (cs_active == hw->cs_active) + return; + ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL); + hw->cs_active = cs_active; +} + +#define __SHIFT_OUT(bits) (SSP_OPCODE_SHIFT | SSP_OUT_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) +#define __SHIFT_IN(bits) (SSP_OPCODE_SHIFT | SSP_IN_MODE | \ + cs_en | clk | SSP_COUNT((bits) * 2 - 1)) + +static int setup_xfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode) +{ + int error, idx = 0; + u32 seqram[16]; + u32 cs_en, cs_dis, clk; + u32 topbits, botbits; + + mode &= MODE_BITS; + if (mode == hw->mode && bpw == hw->bpw) + return 0; + + cs_en = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW; + cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW : SSP_CS_HIGH; + clk = (mode & SPI_CPOL) ? SSP_CLK_HIGH : SSP_CLK_LOW; + + /* Construct instructions */ + + /* Disable Chip Select */ + hw->pc_dis = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_dis | clk; + + /* Enable Chip Select */ + hw->pc_en = idx; + seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Reads and writes need to be split for bpw > 16 */ + topbits = (bpw > 16) ? 16 : bpw; + botbits = bpw - topbits; + + /* Write */ + hw->pc_wr = idx; + seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG; + if (botbits) + seqram[idx++] = __SHIFT_OUT(botbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + /* Read */ + hw->pc_rd = idx; + if (botbits) + seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG; + seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG; + seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk; + + error = ti_ssp_load(hw->dev, 0, seqram, idx); + if (error < 0) + return error; + + error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ? + 0 : SSP_EARLY_DIN)); + if (error < 0) + return error; + + hw->bpw = bpw; + hw->mode = mode; + + return error; +} + +static void ti_ssp_spi_work(struct work_struct *work) +{ + struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work); + + spin_lock(&hw->lock); + + while (!list_empty(&hw->msg_queue)) { + struct spi_message *m; + struct spi_device *spi; + struct spi_transfer *t = NULL; + int status = 0; + + m = container_of(hw->msg_queue.next, struct spi_message, + queue); + + list_del_init(&m->queue); + + spin_unlock(&hw->lock); + + spi = m->spi; + + if (hw->pdata->select) + hw->pdata->select(spi->chip_select); + + list_for_each_entry(t, &m->transfers, transfer_list) { + int bpw = spi->bits_per_word; + int xfer_status; + + if (t->bits_per_word) + bpw = t->bits_per_word; + + if (setup_xfer(hw, bpw, spi->mode) < 0) + break; + + chip_select(hw, 1); + + xfer_status = do_transfer(hw, m, t); + if (xfer_status < 0) + status = xfer_status; + + if (t->delay_usecs) + udelay(t->delay_usecs); + + if (t->cs_change) + chip_select(hw, 0); + } + + chip_select(hw, 0); + m->status = status; + m->complete(m->context); + + spin_lock(&hw->lock); + } + + if (hw->shutdown) + complete(&hw->complete); + + spin_unlock(&hw->lock); +} + +static int ti_ssp_spi_setup(struct spi_device *spi) +{ + if (spi->bits_per_word > 32) + return -EINVAL; + + return 0; +} + +static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m) +{ + struct ti_ssp_spi *hw; + struct spi_transfer *t; + int error = 0; + + m->actual_length = 0; + m->status = -EINPROGRESS; + + hw = spi_master_get_devdata(spi->master); + + if (list_empty(&m->transfers) || !m->complete) + return -EINVAL; + + list_for_each_entry(t, &m->transfers, transfer_list) { + if (t->len && !(t->rx_buf || t->tx_buf)) { + dev_err(&spi->dev, "invalid xfer, no buffer\n"); + return -EINVAL; + } + + if (t->len && t->rx_buf && t->tx_buf) { + dev_err(&spi->dev, "invalid xfer, full duplex\n"); + return -EINVAL; + } + + if (t->bits_per_word > 32) { + dev_err(&spi->dev, "invalid xfer width %d\n", + t->bits_per_word); + return -EINVAL; + } + } + + spin_lock(&hw->lock); + if (hw->shutdown) { + error = -ESHUTDOWN; + goto error_unlock; + } + list_add_tail(&m->queue, &hw->msg_queue); + queue_work(hw->workqueue, &hw->work); +error_unlock: + spin_unlock(&hw->lock); + return error; +} + +static int __devinit ti_ssp_spi_probe(struct platform_device *pdev) +{ + const struct ti_ssp_spi_data *pdata; + struct ti_ssp_spi *hw; + struct spi_master *master; + struct device *dev = &pdev->dev; + int error = 0; + + pdata = dev->platform_data; + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi)); + if (!master) { + dev_err(dev, "cannot allocate SPI master\n"); + return -ENOMEM; + } + + hw = spi_master_get_devdata(master); + platform_set_drvdata(pdev, hw); + + hw->master = master; + hw->dev = dev; + hw->pdata = pdata; + + spin_lock_init(&hw->lock); + init_completion(&hw->complete); + INIT_LIST_HEAD(&hw->msg_queue); + INIT_WORK(&hw->work, ti_ssp_spi_work); + + hw->workqueue = create_singlethread_workqueue(dev_name(dev)); + if (!hw->workqueue) { + error = -ENOMEM; + dev_err(dev, "work queue creation failed\n"); + goto error_wq; + } + + master->bus_num = pdev->id; + master->num_chipselect = hw->pdata->num_cs; + master->mode_bits = MODE_BITS; + master->flags = SPI_MASTER_HALF_DUPLEX; + master->setup = ti_ssp_spi_setup; + master->transfer = ti_ssp_spi_transfer; + + error = spi_register_master(master); + if (error) { + dev_err(dev, "master registration failed\n"); + goto error_reg; + } + + return 0; + +error_reg: + destroy_workqueue(hw->workqueue); +error_wq: + spi_master_put(master); + return error; +} + +static int __devexit ti_ssp_spi_remove(struct platform_device *pdev) +{ + struct ti_ssp_spi *hw = platform_get_drvdata(pdev); + int error; + + hw->shutdown = 1; + while (!list_empty(&hw->msg_queue)) { + error = wait_for_completion_interruptible(&hw->complete); + if (error < 0) { + hw->shutdown = 0; + return error; + } + } + destroy_workqueue(hw->workqueue); + spi_unregister_master(hw->master); + + return 0; +} + +static struct platform_driver ti_ssp_spi_driver = { + .probe = ti_ssp_spi_probe, + .remove = __devexit_p(ti_ssp_spi_remove), + .driver = { + .name = "ti-ssp-spi", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_spi_init(void) +{ + return platform_driver_register(&ti_ssp_spi_driver); +} +subsys_initcall(ti_ssp_spi_init); + +static void __exit ti_ssp_spi_exit(void) +{ + platform_driver_unregister(&ti_ssp_spi_driver); +} +module_exit(ti_ssp_spi_exit); + +MODULE_DESCRIPTION("SSP SPI Master"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:spi_ti_ssp"); -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:24 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:24 -0400 Subject: [PATCH v4 08/12] gpio: add ti-ssp gpio driver In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-9-git-send-email-cyril@ti.com> TI's SSP controller pins can be directly read and written to behave like a GPIO. This patch adds a GPIO driver that exposes such functionality. Acked-by: Grant Likely Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/include/mach/ti_ssp.h | 4 + drivers/gpio/Kconfig | 10 ++ drivers/gpio/Makefile | 1 + drivers/gpio/ti-ssp-gpio.c | 200 +++++++++++++++++++++++++++ 4 files changed, 215 insertions(+), 0 deletions(-) create mode 100644 drivers/gpio/ti-ssp-gpio.c diff --git a/arch/arm/mach-davinci/include/mach/ti_ssp.h b/arch/arm/mach-davinci/include/mach/ti_ssp.h index bff8ef6..8fed5ab 100644 --- a/arch/arm/mach-davinci/include/mach/ti_ssp.h +++ b/arch/arm/mach-davinci/include/mach/ti_ssp.h @@ -39,6 +39,10 @@ struct ti_ssp_spi_data { void (*select)(int cs); }; +struct ti_ssp_gpio_data { + int start; +}; + /* * Sequencer port IO pin configuration bits. These do not correlate 1-1 with * the hardware. The iosel field in the port data combines iosel1 and iosel2, diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 510aa20..e400761 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -111,6 +111,16 @@ config GPIO_SCH This driver can also be built as a module. If so, the module will be called sch-gpio. +config GPIO_TI_SSP + tristate "TI SSP Controller GPIO Driver" + depends on GPIOLIB && TI_SSP + help + Say yes here to support a virtual GPIO interface on TI SSP ports. + Each SSP port translates into 4 GPIOs, with no IRQ support. + + This driver can also be built as a module. If so, the module + will be called ti-ssp-gpio. + comment "I2C GPIO expanders:" config GPIO_MAX7300 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fc6019d..98b4551 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_PL061) += pl061.o obj-$(CONFIG_GPIO_STMPE) += stmpe-gpio.o obj-$(CONFIG_GPIO_TC35892) += tc35892-gpio.o obj-$(CONFIG_GPIO_TIMBERDALE) += timbgpio.o +obj-$(CONFIG_GPIO_TI_SSP) += ti-ssp-gpio.o obj-$(CONFIG_GPIO_TWL4030) += twl4030-gpio.o obj-$(CONFIG_GPIO_UCB1400) += ucb1400_gpio.o obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o diff --git a/drivers/gpio/ti-ssp-gpio.c b/drivers/gpio/ti-ssp-gpio.c new file mode 100644 index 0000000..c046713 --- /dev/null +++ b/drivers/gpio/ti-ssp-gpio.c @@ -0,0 +1,200 @@ +/* + * Sequencer Serial Port (SSP) based virtual GPIO driver + * + * Copyright (C) 2010 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ti_ssp_gpio { + struct gpio_chip chip; +#define chip2gpio(chip) container_of(chip, struct ti_ssp_gpio, chip) + struct device *dev; + spinlock_t lock; + u8 out; + u32 iosel; +}; + +static int direction_in(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error = 0; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_IN); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + spin_unlock(&gpio->lock); + + return error; +} + +static int direction_out(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int error; + + spin_lock(&gpio->lock); + + gpio->iosel &= ~SSP_PIN_MASK(gpio_num); + gpio->iosel |= SSP_PIN_SEL(gpio_num, SSP_OUT); + + error = ti_ssp_set_iosel(gpio->dev, gpio->iosel); + + if (error < 0) + goto error; + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + error = ti_ssp_raw_write(gpio->dev, gpio->out); + +error: + spin_unlock(&gpio->lock); + return error; +} + +static int value_get(struct gpio_chip *chip, unsigned gpio_num) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + int ret; + + spin_lock(&gpio->lock); + + ret = ti_ssp_raw_read(gpio->dev); + if (ret >= 0) + ret = (ret & BIT(gpio_num)) ? 1 : 0; + + spin_unlock(&gpio->lock); + return ret; +} + +static void value_set(struct gpio_chip *chip, unsigned gpio_num, int val) +{ + struct ti_ssp_gpio *gpio = chip2gpio(chip); + + spin_lock(&gpio->lock); + + if (val) + gpio->out |= BIT(gpio_num); + else + gpio->out &= ~BIT(gpio_num); + + ti_ssp_raw_write(gpio->dev, gpio->out); + + spin_unlock(&gpio->lock); +} + +static int __devinit ti_ssp_gpio_probe(struct platform_device *pdev) +{ + const struct ti_ssp_gpio_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct ti_ssp_gpio *gpio; + int error; + + if (!pdata) { + dev_err(dev, "platform data not found\n"); + return -EINVAL; + } + + gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + if (!gpio) { + dev_err(dev, "cannot allocate driver data\n"); + return -ENOMEM; + } + + gpio->dev = dev; + gpio->iosel = SSP_PIN_SEL(0, SSP_IN) | SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | SSP_PIN_SEL(3, SSP_IN); + spin_lock_init(&gpio->lock); + platform_set_drvdata(pdev, gpio); + + gpio->chip.base = pdata->start; + gpio->chip.ngpio = 4; + gpio->chip.dev = &pdev->dev; + gpio->chip.label = "ti_ssp_gpio"; + gpio->chip.owner = THIS_MODULE; + gpio->chip.get = value_get; + gpio->chip.set = value_set; + gpio->chip.direction_input = direction_in; + gpio->chip.direction_output = direction_out; + + error = gpiochip_add(&gpio->chip); + if (error < 0) { + dev_err(dev, "gpio chip registration failed (%d)\n", error); + goto error; + } + + dev_info(dev, "ssp gpio interface registered\n"); + return 0; + +error: + kfree(gpio); + return error; +} + +static int __devexit ti_ssp_gpio_remove(struct platform_device *pdev) +{ + struct ti_ssp_gpio *gpio = platform_get_drvdata(pdev); + int error; + + error = gpiochip_remove(&gpio->chip); + if (error < 0) + return error; + kfree(gpio); + return 0; +} + +static struct platform_driver ti_ssp_gpio_driver = { + .probe = ti_ssp_gpio_probe, + .remove = __devexit_p(ti_ssp_gpio_remove), + .driver = { + .name = "ti-ssp-gpio", + .owner = THIS_MODULE, + }, +}; + +static int __init ti_ssp_gpio_init(void) +{ + return platform_driver_register(&ti_ssp_gpio_driver); +} +subsys_initcall(ti_ssp_gpio_init); + +static void __exit ti_ssp_gpio_exit(void) +{ + platform_driver_unregister(&ti_ssp_gpio_driver); +} +module_exit(ti_ssp_gpio_exit); + +MODULE_DESCRIPTION("GPIO interface for TI-SSP"); +MODULE_AUTHOR("Cyril Chemparathy "); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:ti-ssp-gpio"); -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:21 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:21 -0400 Subject: [PATCH v4 05/12] davinci: add spi devices on tnetv107x evm In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-6-git-send-email-cyril@ti.com> This patch adds definitions for spi devices on the tnetv107x evm platform. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 45 +++++++++++++++++++++++++++ 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index c74ea66..924cf06 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 +#define EVM_SPI_CS_GPIO 54 static int initialize_gpio(int gpio, char *desc) { @@ -203,9 +205,47 @@ static struct matrix_keypad_platform_data keypad_config = { .no_autorepeat = 0, }; +static void spi_select_device(int cs) +{ + static int gpio; + + if (!gpio) { + int ret; + ret = gpio_request(EVM_SPI_CS_GPIO, "spi chipsel"); + if (ret < 0) { + pr_err("cannot open spi chipsel gpio\n"); + gpio = -ENOSYS; + return; + } else { + gpio = EVM_SPI_CS_GPIO; + gpio_direction_output(gpio, 0); + } + } + + if (gpio < 0) + return; + + return gpio_set_value(gpio, cs ? 1 : 0); +} + +static const struct ti_ssp_spi_data spi_master_data = { + .num_cs = 2, + .select = spi_select_device, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [1] = { + .dev_name = "ti-ssp-spi", + .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | + SSP_PIN_SEL(1, SSP_DATA) | + SSP_PIN_SEL(2, SSP_CHIPSEL) | + SSP_PIN_SEL(3, SSP_IN) | + SSP_INPUT_SEL(3), + .pdata = &spi_master_data, + .pdata_size = sizeof(spi_master_data), + }, }, }; @@ -217,6 +257,9 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct spi_board_info spi_info[] __initconst = { +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -224,6 +267,8 @@ static __init void tnetv107x_evm_board_init(void) davinci_cfg_reg_list(ssp_pins); tnetv107x_devices_init(&evm_device_info); + + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:25 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:25 -0400 Subject: [PATCH v4 09/12] davinci: add tnetv107x evm ti-ssp gpio device In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-10-git-send-email-cyril@ti.com> This patch adds definitions to hook up one of the ti-ssp ports to the SSP GPIO driver. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 42ae20f..e0acc13 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -40,6 +40,8 @@ #include #include +#define SSP_GPIO_START 128 + #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 @@ -236,9 +238,22 @@ static const struct ti_ssp_spi_data spi_master_data = { .select = spi_select_device, }; +static const struct ti_ssp_gpio_data ssp_gpio_data = { + .start = SSP_GPIO_START, +}; + static struct ti_ssp_data ssp_config = { .out_clock = 250 * 1000, .dev_data = { + [0] = { + .dev_name = "ti-ssp-gpio", + .iosel = SSP_PIN_SEL(0, SSP_IN) | + SSP_PIN_SEL(1, SSP_IN) | + SSP_PIN_SEL(2, SSP_IN) | + SSP_PIN_SEL(3, SSP_IN), + .pdata = &ssp_gpio_data, + .pdata_size = sizeof(ssp_gpio_data), + }, [1] = { .dev_name = "ti-ssp-spi", .iosel = SSP_PIN_SEL(0, SSP_CLOCK) | -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:26 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:26 -0400 Subject: [PATCH v4 10/12] backlight: add support for tps6116x controller In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-11-git-send-email-cyril@ti.com> TPS6116x is an EasyScale backlight controller device. This driver supports TPS6116x devices connected on a single GPIO. Signed-off-by: Cyril Chemparathy --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile | 2 +- drivers/video/backlight/tps6116x.c | 340 ++++++++++++++++++++++++++++++++++++ 3 files changed, 348 insertions(+), 1 deletions(-) create mode 100644 drivers/video/backlight/tps6116x.c diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index e54a337..06e868e 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -307,6 +307,13 @@ config BACKLIGHT_PCF50633 If you have a backlight driven by a NXP PCF50633 MFD, say Y here to enable its driver. +config BACKLIGHT_TPS6116X + tristate "TPS6116X LCD Backlight" + depends on GENERIC_GPIO + help + This driver controls the LCD backlight level for EasyScale capable + SSP connected backlight controllers. + endif # BACKLIGHT_CLASS_DEVICE endif # BACKLIGHT_LCD_SUPPORT diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 44c0f81..5d407c8 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -35,4 +35,4 @@ obj-$(CONFIG_BACKLIGHT_ADP5520) += adp5520_bl.o obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o - +obj-$(CONFIG_BACKLIGHT_TPS6116X)+= tps6116x.o diff --git a/drivers/video/backlight/tps6116x.c b/drivers/video/backlight/tps6116x.c new file mode 100644 index 0000000..7a9f8ca --- /dev/null +++ b/drivers/video/backlight/tps6116x.c @@ -0,0 +1,340 @@ +/* + * TPS6116X LCD Backlight Controller Driver + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TPS6116X_MAX_INTENSITY 31 +#define TPS6116X_DEFAULT_INTENSITY 10 + +/* Easyscale timing w/ margin (usecs) */ +#define T_POWER_SETTLE 2000 +#define T_ES_DELAY 120 +#define T_ES_DETECT 280 +#define T_ES_WINDOW (1000 - T_ES_DELAY - T_ES_DETECT) +#define T_START 3 +#define T_EOS 3 +#define T_INACTIVE 3 +#define T_ACTIVE (3 * T_INACTIVE) + +#define CMD_SET 0x72 + +struct tps6116x { + struct ti_ssp_device *handle; + struct device *dev; + int gpio, gpio_initialized; + struct mutex lock; + int intensity; + int power; + struct backlight_properties props; + struct backlight_device *bl; + int suspended:1; + struct regulator *regulator; +}; + +static int __set_power(struct tps6116x *hw, int power) +{ + unsigned long flags; + int error; + + power = !!power; + if (power == hw->power) + return 0; /* nothing to do */ + + /* disabling is simple... choke power */ + if (!power) { + error = regulator_disable(hw->regulator); + goto done; + } + + /* set ctrl pin init state for easyscale detection */ + gpio_set_value(hw->gpio, 0); + + error = regulator_enable(hw->regulator); + if (error < 0) + goto done; + + udelay(T_POWER_SETTLE); + + /* + * Now that the controller is powered up, we need to put it into 1-wire + * mode. This is a timing sensitive operation, hence the irq disable. + * Ideally, this should happen rarely, and mostly at init, so disabling + * interrupts for the duration should not be a problem. + */ + local_irq_save(flags); + + gpio_set_value(hw->gpio, 1); + udelay(T_ES_DELAY); + gpio_set_value(hw->gpio, 0); + udelay(T_ES_DETECT); + gpio_set_value(hw->gpio, 1); + + local_irq_restore(flags); + +done: + if (error >= 0) + hw->power = power; + + return error; +} + +static void __write_byte(struct tps6116x *hw, u8 data) +{ + int bit; + + gpio_set_value(hw->gpio, 1); + udelay(T_START); + + for (bit = 0; bit < 8; bit++, data <<= 1) { + int val = data & 0x80; + int t_lo = val ? T_INACTIVE : T_ACTIVE; + int t_hi = val ? T_ACTIVE : T_INACTIVE; + + gpio_set_value(hw->gpio, 0); + udelay(t_lo); + gpio_set_value(hw->gpio, 1); + udelay(t_hi); + } + + gpio_set_value(hw->gpio, 0); + udelay(T_EOS); + gpio_set_value(hw->gpio, 1); +} + +static void __set_intensity(struct tps6116x *hw, int intensity) +{ + unsigned long flags; + + intensity = clamp(intensity, 0, TPS6116X_MAX_INTENSITY); + + local_irq_save(flags); + __write_byte(hw, CMD_SET); + __write_byte(hw, intensity); + local_irq_restore(flags); +} + +static int set_intensity(struct tps6116x *hw, int intensity) +{ + int error = 0; + + if (intensity == hw->intensity) + return 0; + + mutex_lock(&hw->lock); + + if (!hw->gpio_initialized) { + error = gpio_request_one(hw->gpio, GPIOF_DIR_OUT, + dev_name(hw->dev)); + if (error < 0) + goto error; + hw->gpio_initialized = 1; + } + + error = __set_power(hw, intensity ? 1 : 0); + if (error < 0) + goto error; + + if (intensity > 0) + __set_intensity(hw, intensity); + + hw->intensity = intensity; +error: + mutex_unlock(&hw->lock); + + return error; +} + +static ssize_t intensity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "%d\n", hw->intensity); + + return len; +} + +static ssize_t intensity_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct tps6116x *hw = dev_get_drvdata(dev); + unsigned long intensity; + int error; + + error = strict_strtoul(buf, 10, &intensity); + if (error < 0) + return error; + + error = set_intensity(hw, intensity); + if (error < 0) + return error; + + return count; +} + +DEVICE_ATTR(intensity, S_IWUSR | S_IRUGO, intensity_show, intensity_store); + +static int get_brightness(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + + return hw->intensity; +} + +static int update_status(struct backlight_device *bl) +{ + struct tps6116x *hw = bl_get_data(bl); + int intensity = bl->props.brightness; + + if (hw->suspended) + intensity = 0; + if (bl->props.power != FB_BLANK_UNBLANK) + intensity = 0; + if (bl->props.fb_blank != FB_BLANK_UNBLANK) + intensity = 0; + + return set_intensity(hw, intensity); +} + +static const struct backlight_ops tps6116x_backlight_ops = { + .get_brightness = get_brightness, + .update_status = update_status, +}; + +static int __devinit tps6116x_probe(struct platform_device *pdev) +{ + struct tps6116x *hw; + struct device *dev = &pdev->dev; + struct backlight_properties props; + int error; + + hw = kzalloc(sizeof(struct tps6116x), GFP_KERNEL); + if (!hw) { + error = -ENOMEM; + dev_err(dev, "cannot allocate driver data\n"); + goto fail0; + } + platform_set_drvdata(pdev, hw); + + memset(hw, 0, sizeof(struct tps6116x)); + hw->gpio = (int)dev->platform_data; + hw->dev = dev; + + mutex_init(&hw->lock); + + error = device_create_file(dev, &dev_attr_intensity); + if (error < 0) { + dev_err(dev, "cannot create device attributes\n"); + goto fail1; + } + + hw->regulator = regulator_get(dev, "vlcd"); + if (IS_ERR(hw->regulator)) { + error = PTR_ERR(hw->regulator); + dev_err(dev, "cannot claim regulator\n"); + goto fail2; + } + + memset(&props, 0, sizeof(props)); + props.max_brightness = TPS6116X_MAX_INTENSITY; + props.brightness = TPS6116X_DEFAULT_INTENSITY; + + hw->bl = backlight_device_register("tps6116x", hw->dev, hw, + &tps6116x_backlight_ops, &props); + if (IS_ERR(hw->bl)) { + error = PTR_ERR(hw->bl); + dev_err(dev, "backlight registration failed\n"); + goto fail3; + } + + dev_info(dev, "registered backlight controller\n"); + return 0; + +fail3: + regulator_put(hw->regulator); +fail2: + device_remove_file(dev, &dev_attr_intensity); +fail1: + kfree(hw); + platform_set_drvdata(pdev, NULL); +fail0: + return error; +} + +static int __devexit tps6116x_remove(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + + backlight_device_unregister(hw->bl); + regulator_disable(hw->regulator); + regulator_put(hw->regulator); + device_remove_file(hw->dev, &dev_attr_intensity); + kfree(hw); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int tps6116x_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 1; + update_status(hw->bl); + return 0; +} + +static int tps6116x_resume(struct platform_device *pdev) +{ + struct tps6116x *hw = platform_get_drvdata(pdev); + hw->suspended = 0; + update_status(hw->bl); + return 0; +} + +static struct platform_driver tps6116x_driver = { + .probe = tps6116x_probe, + .remove = __devexit_p(tps6116x_remove), + .suspend = tps6116x_suspend, + .resume = tps6116x_resume, + .driver = { + .name = "tps6116x", + .owner = THIS_MODULE, + }, +}; + +static int __init tps6116x_init(void) +{ + return platform_driver_register(&tps6116x_driver); +} +module_init(tps6116x_init); + +static void __exit tps6116x_exit(void) +{ + platform_driver_unregister(&tps6116x_driver); +} +module_exit(tps6116x_exit); + +MODULE_DESCRIPTION("SSP TPS6116X Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tps6116x"); -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:22 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:22 -0400 Subject: [PATCH v4 06/12] regulator: add driver for tps6524x regulator In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-7-git-send-email-cyril@ti.com> TPS6524X provides three step-down converters and two general-purpose LDO voltage regulators. This device is interfaced using SPI. Acked-by: Mark Brown Signed-off-by: Cyril Chemparathy --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps6524x-regulator.c | 692 ++++++++++++++++++++++++++++++++ 3 files changed, 703 insertions(+), 0 deletions(-) create mode 100644 drivers/regulator/tps6524x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 172951b..7875c2e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -235,5 +235,15 @@ config REGULATOR_TPS6586X help This driver supports TPS6586X voltage regulator chips. +config REGULATOR_TPS6524X + tristate "TI TPS6524X Power regulators" + depends on TI_SSP + help + This driver supports TPS6524X voltage regulator chips. TPS6524X + provides three step-down converters and two general-purpose LDO + voltage regulators. This device is interfaced using a customized + serial interface currently supported on the sequencer serial + port controller. + endif diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 8285fd8..a8e5bc0 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c new file mode 100644 index 0000000..6d6cc5e --- /dev/null +++ b/drivers/regulator/tps6524x-regulator.c @@ -0,0 +1,692 @@ +/* + * Regulator driver for TPS6524x PMIC + * + * Copyright (C) 2010 Texas Instruments + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REG_LDO_SET 0x0 +#define LDO_ILIM_MASK 1 /* 0 = 400-800, 1 = 900-1500 */ +#define LDO_VSEL_MASK 0x0f +#define LDO2_ILIM_SHIFT 12 +#define LDO2_VSEL_SHIFT 4 +#define LDO1_ILIM_SHIFT 8 +#define LDO1_VSEL_SHIFT 0 + +#define REG_BLOCK_EN 0x1 +#define BLOCK_MASK 1 +#define BLOCK_LDO1_SHIFT 0 +#define BLOCK_LDO2_SHIFT 1 +#define BLOCK_LCD_SHIFT 2 +#define BLOCK_USB_SHIFT 3 + +#define REG_DCDC_SET 0x2 +#define DCDC_VDCDC_MASK 0x1f +#define DCDC_VDCDC1_SHIFT 0 +#define DCDC_VDCDC2_SHIFT 5 +#define DCDC_VDCDC3_SHIFT 10 + +#define REG_DCDC_EN 0x3 +#define DCDCDCDC_EN_MASK 0x1 +#define DCDCDCDC1_EN_SHIFT 0 +#define DCDCDCDC1_PG_MSK BIT(1) +#define DCDCDCDC2_EN_SHIFT 2 +#define DCDCDCDC2_PG_MSK BIT(3) +#define DCDCDCDC3_EN_SHIFT 4 +#define DCDCDCDC3_PG_MSK BIT(5) + +#define REG_USB 0x4 +#define USB_ILIM_SHIFT 0 +#define USB_ILIM_MASK 0x3 +#define USB_TSD_SHIFT 2 +#define USB_TSD_MASK 0x3 +#define USB_TWARN_SHIFT 4 +#define USB_TWARN_MASK 0x3 +#define USB_IWARN_SD BIT(6) +#define USB_FAST_LOOP BIT(7) + +#define REG_ALARM 0x5 +#define ALARM_LDO1 BIT(0) +#define ALARM_DCDC1 BIT(1) +#define ALARM_DCDC2 BIT(2) +#define ALARM_DCDC3 BIT(3) +#define ALARM_LDO2 BIT(4) +#define ALARM_USB_WARN BIT(5) +#define ALARM_USB_ALARM BIT(6) +#define ALARM_LCD BIT(9) +#define ALARM_TEMP_WARM BIT(10) +#define ALARM_TEMP_HOT BIT(11) +#define ALARM_NRST BIT(14) +#define ALARM_POWERUP BIT(15) + +#define REG_INT_ENABLE 0x6 +#define INT_LDO1 BIT(0) +#define INT_DCDC1 BIT(1) +#define INT_DCDC2 BIT(2) +#define INT_DCDC3 BIT(3) +#define INT_LDO2 BIT(4) +#define INT_USB_WARN BIT(5) +#define INT_USB_ALARM BIT(6) +#define INT_LCD BIT(9) +#define INT_TEMP_WARM BIT(10) +#define INT_TEMP_HOT BIT(11) +#define INT_GLOBAL_EN BIT(15) + +#define REG_INT_STATUS 0x7 +#define STATUS_LDO1 BIT(0) +#define STATUS_DCDC1 BIT(1) +#define STATUS_DCDC2 BIT(2) +#define STATUS_DCDC3 BIT(3) +#define STATUS_LDO2 BIT(4) +#define STATUS_USB_WARN BIT(5) +#define STATUS_USB_ALARM BIT(6) +#define STATUS_LCD BIT(9) +#define STATUS_TEMP_WARM BIT(10) +#define STATUS_TEMP_HOT BIT(11) + +#define REG_SOFTWARE_RESET 0xb +#define REG_WRITE_ENABLE 0xd +#define REG_REV_ID 0xf + +#define N_DCDC 3 +#define N_LDO 2 +#define N_SWITCH 2 +#define N_REGULATORS (3 /* DCDC */ + \ + 2 /* LDO */ + \ + 2 /* switch */) + +#define FIXED_ILIMSEL BIT(0) +#define FIXED_VOLTAGE BIT(1) + +#define CMD_READ(reg) ((reg) << 6) +#define CMD_WRITE(reg) (BIT(5) | (reg) << 6) +#define STAT_CLK BIT(3) +#define STAT_WRITE BIT(2) +#define STAT_INVALID BIT(1) +#define STAT_WP BIT(0) + +struct field { + int reg; + int shift; + int mask; +}; + +struct supply_info { + const char *name; + int n_voltages; + const int *voltages; + int fixed_voltage; + int n_ilimsels; + const int *ilimsels; + int fixed_ilimsel; + int flags; + struct field enable, voltage, ilimsel; +}; + +struct tps6524x { + struct device *dev; + struct spi_device *spi; + struct mutex lock; + struct regulator_desc desc[N_REGULATORS]; + struct regulator_dev *rdev[N_REGULATORS]; +}; + +static int __read_reg(struct tps6524x *hw, int reg) +{ + int error = 0; + u16 cmd = CMD_READ(reg), in; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].rx_buf = ∈ + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "read reg %d, data %x, status %x\n", + reg, in, status); + + if (!(status & STAT_CLK) || (status & STAT_WRITE)) + return -EIO; + + if (status & STAT_INVALID) + return -EINVAL; + + return in; +} + +static int read_reg(struct tps6524x *hw, int reg) +{ + int ret; + + mutex_lock(&hw->lock); + ret = __read_reg(hw, reg); + mutex_unlock(&hw->lock); + + return ret; +} + +static int __write_reg(struct tps6524x *hw, int reg, int val) +{ + int error = 0; + u16 cmd = CMD_WRITE(reg), out = val; + u8 status; + struct spi_message m; + struct spi_transfer t[3]; + + spi_message_init(&m); + memset(t, 0, sizeof(t)); + + t[0].tx_buf = &cmd; + t[0].len = 2; + t[0].bits_per_word = 12; + spi_message_add_tail(&t[0], &m); + + t[1].tx_buf = &out; + t[1].len = 2; + t[1].bits_per_word = 16; + spi_message_add_tail(&t[1], &m); + + t[2].rx_buf = &status; + t[2].len = 1; + t[2].bits_per_word = 4; + spi_message_add_tail(&t[2], &m); + + error = spi_sync(hw->spi, &m); + if (error < 0) + return error; + + dev_dbg(hw->dev, "wrote reg %d, data %x, status %x\n", + reg, out, status); + + if (!(status & STAT_CLK) || !(status & STAT_WRITE)) + return -EIO; + + if (status & (STAT_INVALID | STAT_WP)) + return -EINVAL; + + return error; +} + +static int __rmw_reg(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + ret = __read_reg(hw, reg); + if (ret < 0) + return ret; + + ret &= ~mask; + ret |= val; + + ret = __write_reg(hw, reg, ret); + + return (ret < 0) ? ret : 0; +} + +static int rmw_protect(struct tps6524x *hw, int reg, int mask, int val) +{ + int ret; + + mutex_lock(&hw->lock); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 1); + if (ret) { + dev_err(hw->dev, "failed to set write enable\n"); + goto error; + } + + ret = __rmw_reg(hw, reg, mask, val); + if (ret) + dev_err(hw->dev, "failed to rmw register %d\n", reg); + + ret = __write_reg(hw, REG_WRITE_ENABLE, 0); + if (ret) { + dev_err(hw->dev, "failed to clear write enable\n"); + goto error; + } + +error: + mutex_unlock(&hw->lock); + + return ret; +} + +static int read_field(struct tps6524x *hw, const struct field *field) +{ + int tmp; + + tmp = read_reg(hw, field->reg); + if (tmp < 0) + return tmp; + + return (tmp >> field->shift) & field->mask; +} + +static int write_field(struct tps6524x *hw, const struct field *field, + int val) +{ + if (val & ~field->mask) + return -EOVERFLOW; + + return rmw_protect(hw, field->reg, + field->mask << field->shift, + val << field->shift); +} + +static const int dcdc1_voltages[] = { + 800000, 825000, 850000, 875000, + 900000, 925000, 950000, 975000, + 1000000, 1025000, 1050000, 1075000, + 1100000, 1125000, 1150000, 1175000, + 1200000, 1225000, 1250000, 1275000, + 1300000, 1325000, 1350000, 1375000, + 1400000, 1425000, 1450000, 1475000, + 1500000, 1525000, 1550000, 1575000, +}; + +static const int dcdc2_voltages[] = { + 1400000, 1450000, 1500000, 1550000, + 1600000, 1650000, 1700000, 1750000, + 1800000, 1850000, 1900000, 1950000, + 2000000, 2050000, 2100000, 2150000, + 2200000, 2250000, 2300000, 2350000, + 2400000, 2450000, 2500000, 2550000, + 2600000, 2650000, 2700000, 2750000, + 2800000, 2850000, 2900000, 2950000, +}; + +static const int dcdc3_voltages[] = { + 2400000, 2450000, 2500000, 2550000, 2600000, + 2650000, 2700000, 2750000, 2800000, 2850000, + 2900000, 2950000, 3000000, 3050000, 3100000, + 3150000, 3200000, 3250000, 3300000, 3350000, + 3400000, 3450000, 3500000, 3550000, 3600000, +}; + +static const int ldo1_voltages[] = { + 4300000, 4350000, 4400000, 4450000, + 4500000, 4550000, 4600000, 4650000, + 4700000, 4750000, 4800000, 4850000, + 4900000, 4950000, 5000000, 5050000, +}; + +static const int ldo2_voltages[] = { + 1100000, 1150000, 1200000, 1250000, + 1300000, 1700000, 1750000, 1800000, + 1850000, 1900000, 3150000, 3200000, + 3250000, 3300000, 3350000, 3400000, +}; + +static const int ldo_ilimsel[] = { + 400000, 1500000 +}; + +static const int usb_ilimsel[] = { + 200000, 400000, 800000, 1000000 +}; + +#define __MK_FIELD(_reg, _mask, _shift) \ + { .reg = (_reg), .mask = (_mask), .shift = (_shift), } + +static const struct supply_info supply_info[N_REGULATORS] = { + { + .name = "DCDC1", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc1_voltages), + .voltages = dcdc1_voltages, + .fixed_ilimsel = 2400000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC1_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC1_SHIFT), + }, + { + .name = "DCDC2", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc2_voltages), + .voltages = dcdc2_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC2_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC2_SHIFT), + }, + { + .name = "DCDC3", + .flags = FIXED_ILIMSEL, + .n_voltages = ARRAY_SIZE(dcdc3_voltages), + .voltages = dcdc3_voltages, + .fixed_ilimsel = 1200000, + .enable = __MK_FIELD(REG_DCDC_EN, DCDCDCDC_EN_MASK, + DCDCDCDC3_EN_SHIFT), + .voltage = __MK_FIELD(REG_DCDC_SET, DCDC_VDCDC_MASK, + DCDC_VDCDC3_SHIFT), + }, + { + .name = "LDO1", + .n_voltages = ARRAY_SIZE(ldo1_voltages), + .voltages = ldo1_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO1_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO1_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO1_ILIM_SHIFT), + }, + { + .name = "LDO2", + .n_voltages = ARRAY_SIZE(ldo2_voltages), + .voltages = ldo2_voltages, + .n_ilimsels = ARRAY_SIZE(ldo_ilimsel), + .ilimsels = ldo_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LDO2_SHIFT), + .voltage = __MK_FIELD(REG_LDO_SET, LDO_VSEL_MASK, + LDO2_VSEL_SHIFT), + .ilimsel = __MK_FIELD(REG_LDO_SET, LDO_ILIM_MASK, + LDO2_ILIM_SHIFT), + }, + { + .name = "USB", + .flags = FIXED_VOLTAGE, + .fixed_voltage = 5000000, + .n_ilimsels = ARRAY_SIZE(usb_ilimsel), + .ilimsels = usb_ilimsel, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_USB_SHIFT), + .ilimsel = __MK_FIELD(REG_USB, USB_ILIM_MASK, + USB_ILIM_SHIFT), + }, + { + .name = "LCD", + .flags = FIXED_VOLTAGE | FIXED_ILIMSEL, + .fixed_voltage = 5000000, + .fixed_ilimsel = 400000, + .enable = __MK_FIELD(REG_BLOCK_EN, BLOCK_MASK, + BLOCK_LCD_SHIFT), + }, +}; + +static int list_voltage(struct regulator_dev *rdev, unsigned selector) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return selector ? -EINVAL : info->fixed_voltage; + + if (selector < 0 || selector >= info->n_voltages) + return -EINVAL; + + return info->voltages[selector]; +} + +static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return -EINVAL; + + for (i = 0; i < info->n_voltages; i++) + if (min_uV <= info->voltages[i] && + max_uV >= info->voltages[i]) + break; + + if (i >= info->n_voltages) + return -EINVAL; + + return write_field(hw, &info->voltage, i); +} + +static int get_voltage(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_VOLTAGE) + return info->fixed_voltage; + + ret = read_field(hw, &info->voltage); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_voltages)) + return -EIO; + + return info->voltages[ret]; +} + +static int set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + const struct supply_info *info; + struct tps6524x *hw; + int i; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return -EINVAL; + + for (i = 0; i < info->n_ilimsels; i++) + if (min_uA <= info->ilimsels[i] && + max_uA >= info->ilimsels[i]) + break; + + if (i >= info->n_ilimsels) + return -EINVAL; + + return write_field(hw, &info->ilimsel, i); +} + +static int get_current_limit(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + int ret; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + if (info->flags & FIXED_ILIMSEL) + return info->fixed_ilimsel; + + ret = read_field(hw, &info->ilimsel); + if (ret < 0) + return ret; + if (WARN_ON(ret >= info->n_ilimsels)) + return -EIO; + + return info->ilimsels[ret]; +} + +static int enable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 1); +} + +static int disable_supply(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return write_field(hw, &info->enable, 0); +} + +static int is_supply_enabled(struct regulator_dev *rdev) +{ + const struct supply_info *info; + struct tps6524x *hw; + + hw = rdev_get_drvdata(rdev); + info = &supply_info[rdev_get_id(rdev)]; + + return read_field(hw, &info->enable); +} + +static struct regulator_ops regulator_ops = { + .is_enabled = is_supply_enabled, + .enable = enable_supply, + .disable = disable_supply, + .get_voltage = get_voltage, + .set_voltage = set_voltage, + .list_voltage = list_voltage, + .set_current_limit = set_current_limit, + .get_current_limit = get_current_limit, +}; + +static int __devexit pmic_remove(struct spi_device *spi) +{ + struct tps6524x *hw = spi_get_drvdata(spi); + int i; + + if (!hw) + return 0; + for (i = 0; i < N_REGULATORS; i++) { + if (hw->rdev[i]) + regulator_unregister(hw->rdev[i]); + hw->rdev[i] = NULL; + } + spi_set_drvdata(spi, NULL); + kfree(hw); + return 0; +} + +static int __devinit pmic_probe(struct spi_device *spi) +{ + struct tps6524x *hw; + struct device *dev = &spi->dev; + const struct supply_info *info = supply_info; + struct regulator_init_data *init_data; + int ret = 0, i; + + init_data = dev->platform_data; + if (!init_data) { + dev_err(dev, "could not find regulator platform data\n"); + return -EINVAL; + } + + hw = kzalloc(sizeof(struct tps6524x), GFP_KERNEL); + if (!hw) { + dev_err(dev, "cannot allocate regulator private data\n"); + return -ENOMEM; + } + spi_set_drvdata(spi, hw); + + memset(hw, 0, sizeof(struct tps6524x)); + hw->dev = dev; + hw->spi = spi_dev_get(spi); + mutex_init(&hw->lock); + + for (i = 0; i < N_REGULATORS; i++, info++, init_data++) { + hw->desc[i].name = info->name; + hw->desc[i].id = i; + hw->desc[i].n_voltages = info->n_voltages; + hw->desc[i].ops = ®ulator_ops; + hw->desc[i].type = REGULATOR_VOLTAGE; + hw->desc[i].owner = THIS_MODULE; + + if (info->flags & FIXED_VOLTAGE) + hw->desc[i].n_voltages = 1; + + hw->rdev[i] = regulator_register(&hw->desc[i], dev, + init_data, hw); + if (IS_ERR(hw->rdev[i])) { + ret = PTR_ERR(hw->rdev[i]); + hw->rdev[i] = NULL; + goto fail; + } + } + + return 0; + +fail: + pmic_remove(spi); + return ret; +} + +static struct spi_driver pmic_driver = { + .probe = pmic_probe, + .remove = __devexit_p(pmic_remove), + .driver = { + .name = "tps6524x", + .owner = THIS_MODULE, + }, +}; + +static int __init pmic_driver_init(void) +{ + return spi_register_driver(&pmic_driver); +} +subsys_initcall_sync(pmic_driver_init); + +static void __exit pmic_driver_exit(void) +{ + spi_unregister_driver(&pmic_driver); +} +module_exit(pmic_driver_exit); + +MODULE_DESCRIPTION("TPS6524X PMIC Driver"); +MODULE_AUTHOR("Cyril Chemparathy"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("spi:tps6524x"); -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:23 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:23 -0400 Subject: [PATCH v4 07/12] davinci: add tnetv107x evm regulators In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-8-git-send-email-cyril@ti.com> This patch adds regulator and spi board info definitions for the tps6524x power management IC found on tnetv107x evm boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 85 +++++++++++++++++++++++++++ 1 files changed, 85 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 924cf06..42ae20f 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -257,7 +260,89 @@ static struct tnetv107x_device_info evm_device_info __initconst = { .ssp_config = &ssp_config, }; +static struct regulator_consumer_supply usb_consumers[] = { + REGULATOR_SUPPLY("vbus", "musb_hdrc.1"), +}; + +static struct regulator_consumer_supply lcd_consumers[] = { + REGULATOR_SUPPLY("vlcd", "tps6116x"), +}; + +static struct regulator_init_data regulators[] = { + { + .constraints = { + .name = "DCDC1", + .min_uV = 1000000, + .max_uV = 1000000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC2", + .min_uV = 1800000, + .max_uV = 1800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "DCDC3", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 4800000, + .max_uV = 4800000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .constraints = { + .name = "LDO1", + .min_uV = 3300000, + .max_uV = 3300000, + .always_on = 1, + .boot_on = 1, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(usb_consumers), + .consumer_supplies = usb_consumers, + .constraints = { + .name = "USB", + .min_uA = 200000, + .max_uA = 1000000, + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | + REGULATOR_CHANGE_STATUS, + }, + }, + { + .num_consumer_supplies = ARRAY_SIZE(lcd_consumers), + .consumer_supplies = lcd_consumers, + .constraints = { + .name = "LCD", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + }, +}; + static struct spi_board_info spi_info[] __initconst = { + { + .modalias = "tps6524x", + .bus_num = 1, + .chip_select = 0, + .mode = SPI_MODE_0, + .platform_data = regulators, + }, }; static __init void tnetv107x_evm_board_init(void) -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:27 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:27 -0400 Subject: [PATCH v4 11/12] davinci: add tnetv107x evm backlight device In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-12-git-send-email-cyril@ti.com> The tnetv107x evm board has a backlight device that is connected on one of the SSP ports. This patch adds the board definitions necessary to plug the backlight driver to the GPIO corresponding to this SSP pin. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index e0acc13..e7f413e 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -45,6 +45,7 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) { @@ -360,6 +361,12 @@ static struct spi_board_info spi_info[] __initconst = { }, }; +static struct platform_device backlight_device = { + .name = "tps6116x", + .id = -1, + .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -368,6 +375,8 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); + platform_device_register(&backlight_device); + spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); } -- 1.7.0.4 From cyril at ti.com Tue Oct 26 15:18:28 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Tue, 26 Oct 2010 16:18:28 -0400 Subject: [PATCH v4 12/12] davinci: add tnetv107x evm i2c eeprom device In-Reply-To: <1288124308-14999-1-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> Message-ID: <1288124308-14999-13-git-send-email-cyril@ti.com> The tnetv107x evm board has an I2C device connected on one of the SSP ports. This patch adds board definitions for a GPIO based I2C master, as well as definitions for the eeprom device on these boards. Signed-off-by: Cyril Chemparathy --- arch/arm/mach-davinci/board-tnetv107x-evm.c | 30 +++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index e7f413e..ff3d8dd 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include #include @@ -45,6 +48,8 @@ #define EVM_MMC_WP_GPIO 21 #define EVM_MMC_CD_GPIO 24 #define EVM_SPI_CS_GPIO 54 +#define EVM_I2C_SDA_GPIO (SSP_GPIO_START + 0) +#define EVM_I2C_SCL_GPIO (SSP_GPIO_START + 1) #define EVM_BACKLIGHT_GPIO (SSP_GPIO_START + 2) static int initialize_gpio(int gpio, char *desc) @@ -367,6 +372,29 @@ static struct platform_device backlight_device = { .dev.platform_data = (void *)EVM_BACKLIGHT_GPIO, }; +struct i2c_gpio_platform_data i2c_data = { + .sda_pin = EVM_I2C_SDA_GPIO, + .scl_pin = EVM_I2C_SCL_GPIO, +}; + +static struct platform_device i2c_device = { + .name = "i2c-gpio", + .id = 0, + .dev.platform_data = &i2c_data, +}; + +static struct at24_platform_data at24_config = { + .byte_len = SZ_16K / 8, + .page_size = 16, +}; + +static struct i2c_board_info i2c_info[] __initconst = { + { + I2C_BOARD_INFO("24c16", 0x50), + .platform_data = &at24_config, + }, +}; + static __init void tnetv107x_evm_board_init(void) { davinci_cfg_reg_list(sdio1_pins); @@ -376,8 +404,10 @@ static __init void tnetv107x_evm_board_init(void) tnetv107x_devices_init(&evm_device_info); platform_device_register(&backlight_device); + platform_device_register(&i2c_device); spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); + i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); } #ifdef CONFIG_SERIAL_8250_CONSOLE -- 1.7.0.4 From tbruno at neuros.us Wed Oct 27 08:41:28 2010 From: tbruno at neuros.us (Tom Bruno) Date: Wed, 27 Oct 2010 08:41:28 -0500 Subject: unsubscribe Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: From cyril at ti.com Thu Oct 28 11:09:35 2010 From: cyril at ti.com (Cyril Chemparathy) Date: Thu, 28 Oct 2010 12:09:35 -0400 Subject: [PATCH v4 01/12] misc: add driver for sequencer serial port In-Reply-To: References: <1288124308-14999-1-git-send-email-cyril@ti.com> <1288124308-14999-2-git-send-email-cyril@ti.com> Message-ID: <4CC9A03F.80401@ti.com> On 10/28/2010 11:49 AM, Linus Walleij wrote: > 2010/10/26 Cyril Chemparathy : > >> TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port >> device. It has a built-in programmable execution engine that can be programmed >> to operate as almost any serial bus (I2C, SPI, EasyScale, and others). >> >> This patch adds a driver for this controller device. The driver does not >> expose a user-land interface. Protocol drivers built on top of this layer are >> expected to remain in-kernel. > > Why is this thing in drivers/misc? > > drivers/mfd is IMHO the apropriate place for a driver like this, and > the subdrivers should be migrated to use mfd cells and platform > drivers for the subdevices. > > All functions and abstractions you create here look suspiciously > lot like other MFD devices. > > But please, beat me up if I'm wrong! Alan had raised the same concern earlier, and my response was: > Unlike MFDs, this device doesn't have cells with differing > functionality. Instead it has functionally identical ports that can > operate in a variety of modes. That said, does this still fit in with > other MFD drivers? If so, I don't see a problem with moving it there. I don't see a problem with moving this into MFD, but this won't be able to use any of the functionality provided by mfd-core. Thanks Cyril. From greg at kroah.com Thu Oct 28 12:46:22 2010 From: greg at kroah.com (Greg KH) Date: Thu, 28 Oct 2010 10:46:22 -0700 Subject: Which is going to be the latest kernel version for this year In-Reply-To: References: Message-ID: <20101028174622.GA2102@kroah.com> On Thu, Oct 28, 2010 at 10:26:08AM -0500, Victor Rodriguez wrote: > Hey I want to know which is going to be the latest kernel version for this year Why does it matter? > Is possible to have the v2.6.37 merge window > > but do you think that could be possible to have v2.6.38 ? This question does not make sense at all. Have you read the files in Documentation/development_process/ for how the kernel is developed and released? thanks, greg k-h From chtpatil at gmail.com Wed Oct 27 11:36:12 2010 From: chtpatil at gmail.com (chetan patil) Date: Wed, 27 Oct 2010 22:06:12 +0530 Subject: NFS In-Reply-To: References: Message-ID: *I want to boot the borad using NFS.* My Dm64446 has ::: Linux-2.6.10_mvl401-davinci_evm My fedora 12 host has ::: kernel version 2.6.32 I think updating kernel of DM6446 is risky business. Is there any other option. And you sure we need to update kernel only? Please check page no. 4-11 of attached doc. Is there any problem with the target filesys with permission set for writing to the shared area. After booting i get::: TirDavinci_EVM# boot ## Booting image at 02050000 ... Image Name: Linux-2.6.10_mvl401-davinci_evm Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1324188 Bytes = 1.3 MB Load Address: 80008000 Entry Point: 80008000 Verifying Checksum ... OK OK Starting Davinci linux kernel... Uncompressing Linux.................................................................................................. done, booting thee Linux version 2.6.10 CPU: ARM926EJ-Sid(wb) [41069265] revision 5 (ARMv5TEJ) CPU0: D VIVT write-back cache CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets CPU0: D cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets Machine: DaVinci EVM the command is console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.1.5:/home/chetanpatil/workdir/filesys ip=dhcp Memory policy: ECC disabled, Data cache writeback Built 1 zonelists Kernel command line: mem=120M console=ttyS0,115200n8 root=/dev/nfs rw nfsroot=192.168.1.5:/home/chetanpatil/workdir/filesys ip=dhcp PID hash table entries: 512 (order: 9, 8192 bytes) Console: colour dummy device 80x30 Dentry cache hash table entries: 16384 (order: 4, 65536 bytes) Inode-cache hash table entries: 8192 (order: 3, 32768 bytes) Memory: 120MB = 120MB total Memory: 118528KB available (2210K code, 470K data, 532K init) Mount-cache hash table entries: 512 (order: 0, 4096 bytes) CPU: Testing write buffer coherency: ok spawn_desched_task(00000000) desched cpu_callback 3/00000000 ksoftirqd started up. desched cpu_callback 2/00000000 desched thread 0 started up. NET: Registered protocol family 16 Registering platform device 'nor_davinci.0'. Parent at platform Registering platform device 'nand_davinci.0'. Parent at platform Registering platform device 'musb_hdrc'. Parent at platform DaVinci I2C DEBUG: 06:14:40 Jun 24 2010 Registering platform device 'i2c'. Parent at platform usbcore: registered new driver usbfs usbcore: registered new driver hub i2c attach client ****. JFFS2 version 2.2. (NAND) (C) 2001-2003 Red Hat, Inc. Registering platform device 'davincifb.0'. Parent at platform Console: switching to colour frame buffer device 90x30 Registering platform device 'davinci_resizer.2'. Parent at platform Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled Registering platform device 'serial8250'. Parent at platform ttyS0 at MMIO 0x1c20000 (irq = 40) is a 16550A io scheduler noop registered io scheduler anticipatory registered RAMDISK driver initialized: 1 RAM disks of 32768K size 1024 blocksize Registering platform device 'ti_davinci_emac'. Parent at platform TI DaVinci EMAC: MAC address is 00:c0:45:c0:c0:ac TI DaVinci EMAC Linux version updated 4.0 TI DaVinci EMAC: Installed 1 instances. netconsole: not configured, aborting i2c /dev entries driver Linux video capture interface: v1.00 Registering platform device 'vpfe.1'. Parent at platform DaVinci v4l2 capture driver V1.0 loaded elevator: using anticipatory as default io scheduler DaVinci flash: probing 16-bit flash bus DaVinci flash: Probing for AMD compatible flash... DaVinci flash: Found 1 x 16MiB AMD AM29LV256M at 0x0 Unlocking the entire NOR flash. Creating 4 MTD partitions on "DaVinci flash": 0x00000000-0x00020000 : "bootloader" 0x00020000-0x00040000 : "params" 0x00040000-0x00440000 : "kernel" 0x00440000-0x01000000 : "filesystem" mice: PS/2 mouse device common for all mice musb_hdrc: version 2.2a/db-0.4.8 [pio] [host] [debug=0] musb_hdrc: USB Host mode controller at c8060000 using PIO, IRQ 12 musb_hdrc musb_hdrc: new USB bus registered, assigned bus number 1 hub 1-0:1.0: USB hub found hub 1-0:1.0: 1 port detected Registering platform device 'davinci-audio.0'. Parent at platform NET: Registered protocol family 2 IP: routing cache hash table of 512 buckets, 4Kbytes TCP: Hash tables configured (established 8192 bind 16384) NET: Registered protocol family 1 NET: Registered protocol family 17 Sending DHCP requests .., OK IP-Config: Got DHCP answer from 0.0.0.0, my address is 192.168.1.6 IP-Config: Complete: device=eth0, addr=192.168.1.6, mask=255.255.255.0, gw=192.168.1.1, host=192.168.1.6, domain=, nis-domain=(none), bootserver=0.0.0.0, rootserver=192.168.1.5, rootpath= Looking up port of RPC 100003/2 on 192.168.1.5 Looking up port of RPC 100005/1 on 192.168.1.5 VFS: Mounted root (nfs filesystem). Freeing init memory: 532K FATAKernel panic - not syncing: Attempted to kill init! L: kernel too ol d prin^H^H^H On Wed, Oct 27, 2010 at 9:21 PM, Steve Chen wrote: > On Wed, Oct 27, 2010 at 10:40 AM, chetan patil wrote: > > How?? > > You can find some useful info here. > > http://processors.wiki.ti.com/index.php/Linux_Toolchain > > > > > Kernel of DM6446 is corrupted?? > > The message basically is saying that the kernel you are using to boot > DM6446 is too old for the file system. Your choices are > 1. Use a newer kernel > 2. Use an older filesystem that would work with your kernel version. > > Steve > -- Regards, Chetan Arvind Patil, +919970018364 http://sites.google.com/site/chtpatil/ -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: sprue66f.pdf Type: application/pdf Size: 1818029 bytes Desc: not available URL: From swapashtekar at gmail.com Wed Oct 27 14:04:08 2010 From: swapashtekar at gmail.com (Swapnil Ashtekar) Date: Thu, 28 Oct 2010 00:34:08 +0530 Subject: MV_doubt Message-ID: Hey, I want to boot the DM6446 via SD/mmc card. How to boot it ? Is there any way for the booting through AEMIF ? -- Regards, Swapnil Ashtekar -------------- next part -------------- An HTML attachment was scrubbed... URL: From =?UTF-8?B?IlNpbmdhcG9yZSBDaXRpemVuIE1yLiBUZW8gRW4gTWluZyAoWmhhbmcgRQ==?= Thu Oct 28 10:43:46 2010 From: =?UTF-8?B?IlNpbmdhcG9yZSBDaXRpemVuIE1yLiBUZW8gRW4gTWluZyAoWmhhbmcgRQ==?= (=?UTF-8?B?IlNpbmdhcG9yZSBDaXRpemVuIE1yLiBUZW8gRW4gTWluZyAoWmhhbmcgRQ==?=) Date: Thu, 28 Oct 2010 23:43:46 +0800 Subject: Which is going to be the latest kernel version for this year In-Reply-To: References: Message-ID: <4CC99A32.1060307@gmail.com> Victor, I think it could be 2.6.38 by the end of this year (2010). -- Yours sincerely, Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? Dip(Mechatronics) BEng(Hons)(Mechanical Engineering) Singapore Identity Card No.: S78*6*2*H Location: Bedok Reservoir Road, Singapore ZIP: 470103 Mobile Phone (Starhub Pre-paid): +65-8369-2618 Windows Live Messenger: teoenming-at-hotmail.com My Youtube videos: http://www.youtube.com/user/enmingteo Alma Maters: [1] Singapore Polytechnic (Graduated 1998) [2] National University of Singapore (Graduated 2006) My Open Letter (Plea for Medical Help/Assistance) to World Leaders (Updated 28 August 2010):- http://lists.mcs.anl.gov/pipermail/mpich-discuss/2010-August/007811.html http://mythtv.org/pipermail/mythtv-users/2010-August/295952.html http://archives.gentoo.org/gentoo-user/msg_f6a341d9623fda17880159b137c07335.xml Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #1: http://i.imgur.com/M1FNX.jpg Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #2: http://i51.tinypic.com/11u9irm.jpg Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #3: http://www.imagevimage.com/images/Singapore_Citizen_Mr._Teo_En_Ming_%28Zhang_Enming%29.jpg Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #4: http://www.merrypic.com/files/o397beqo7qw8wky5rjno.jpg Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #5: http://piczasso.com/i/yicuz.jpg Photograph of Singapore Citizen Mr. Teo En Ming (Zhang Enming) ??? #6: http://www.freeimagehosting.net/uploads/1b553b21ae.jpg On 10/28/2010 11:26 PM, Victor Rodriguez wrote: > Hey I want to know which is going to be the latest kernel version for this year > > Is possible to have the v2.6.37 merge window > > but do you think that could be possible to have v2.6.38 ? > > Thanks for your help > > Victor Rodriguez > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ > > From linus.ml.walleij at gmail.com Thu Oct 28 10:49:06 2010 From: linus.ml.walleij at gmail.com (Linus Walleij) Date: Thu, 28 Oct 2010 11:49:06 -0400 Subject: [PATCH v4 01/12] misc: add driver for sequencer serial port In-Reply-To: <1288124308-14999-2-git-send-email-cyril@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> <1288124308-14999-2-git-send-email-cyril@ti.com> Message-ID: 2010/10/26 Cyril Chemparathy : > TI's sequencer serial port (TI-SSP) is a jack-of-all-trades type of serial port > device. ?It has a built-in programmable execution engine that can be programmed > to operate as almost any serial bus (I2C, SPI, EasyScale, and others). > > This patch adds a driver for this controller device. ?The driver does not > expose a user-land interface. ?Protocol drivers built on top of this layer are > expected to remain in-kernel. Why is this thing in drivers/misc? drivers/mfd is IMHO the apropriate place for a driver like this, and the subdrivers should be migrated to use mfd cells and platform drivers for the subdevices. All functions and abstractions you create here look suspiciously lot like other MFD devices. But please, beat me up if I'm wrong! Yours, Linus Walleij From vm.rod25 at gmail.com Thu Oct 28 11:18:49 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 11:18:49 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 9:34 AM, Nori, Sekhar wrote: > On Thu, Oct 28, 2010 at 19:51:28, Victor Rodriguez wrote: > >> Ok so let me see if I understand The only change that I should do is to remove >> >> > + ? ? if (!machine_is_omapl138_hawkboard()) >> > + ? ? ? ? ? ? return; >> >> right ? >> > > Yes. > > Thanks, > Sekhar > The change is ready and running but I have a question if the new patch apply fine and any other patches of the series has been changed should i send all the patches again like patchv6 ? or should i send this EMAC patch like resend patch ? I do not thick so but if it is necessary I will do it Thanks and regards Victor Rodriguez From vm.rod25 at gmail.com Thu Oct 28 11:20:55 2010 From: vm.rod25 at gmail.com (Victor Rodriguez) Date: Thu, 28 Oct 2010 11:20:55 -0500 Subject: [PATCH v5 1/9] davinci: EMAC support for Omapl138-Hawkboard In-Reply-To: References: <1287511587-22216-1-git-send-email-vm.rod25@gmail.com> <1287511587-22216-2-git-send-email-vm.rod25@gmail.com> Message-ID: On Thu, Oct 28, 2010 at 9:34 AM, Nori, Sekhar wrote: > On Thu, Oct 28, 2010 at 19:51:28, Victor Rodriguez wrote: > >> Ok so let me see if I understand The only change that I should do is to remove >> >> > + ? ? if (!machine_is_omapl138_hawkboard()) >> > + ? ? ? ? ? ? return; >> >> right ? >> > > Yes. > > Thanks, > Sekhar > > The change is ready and running but I have a question if the new patch apply fine and any other patches of the series has been changed should i send all the patches again like patchv6 ? or should i send this EMAC patch like resend patch ? I do not thick so but if it is necessary I will do it Thanks and regards Victor Rodriguez From swapashtekar at gmail.com Thu Oct 28 12:36:42 2010 From: swapashtekar at gmail.com (Swapnil Ashtekar) Date: Thu, 28 Oct 2010 23:06:42 +0530 Subject: Dynamically Loadable Kernel Module Message-ID: Hey, I want to find whether my DM6446 kernel will work with the SD card device drivers using Dynamically Loadable Kernel Module ? Also suggest some patch files to link between the fedora and monta vista linux ? Please do reply asap. -- Regards Swapnil Ashtekar -------------- next part -------------- An HTML attachment was scrubbed... URL: From linus.ml.walleij at gmail.com Thu Oct 28 13:14:14 2010 From: linus.ml.walleij at gmail.com (Linus Walleij) Date: Thu, 28 Oct 2010 14:14:14 -0400 Subject: [PATCH v4 01/12] misc: add driver for sequencer serial port In-Reply-To: <4CC9A03F.80401@ti.com> References: <1288124308-14999-1-git-send-email-cyril@ti.com> <1288124308-14999-2-git-send-email-cyril@ti.com> <4CC9A03F.80401@ti.com> Message-ID: 2010/10/28 Cyril Chemparathy : > On 10/28/2010 11:49 AM, Linus Walleij wrote: >> Why is this thing in drivers/misc? >> drivers/mfd is IMHO the apropriate place for a driver like this, (...) > > Alan had raised the same concern earlier, and my response was: > >[Cyril] >> Unlike MFDs, this device doesn't have cells with differing >> functionality. ?Instead it has functionally identical ports that can >> operate in a variety of modes. ?That said, does this still fit in with >> other MFD drivers? ?If so, I don't see a problem with moving it there. > > I don't see a problem with moving this into MFD, but this won't be able > to use any of the functionality provided by mfd-core. I think they do have differing functionality, though not in their essence (hardware), they do get a clearly defined role at run-time. Sam will tell, but since you have subdrivers in other subsystems MFD fits best IMHO. What about the platform data passed into the MFD driver defines what type of functionality will be assigned to each physical block, from that you create the array of MFD cells to be spawn and spawn it off. Then you have platform_driver:s in each subsystem attaching to said cells. Shouldn't be too hard. Yours, Linus Walleij