LAN9221 with Samsumg S3C2416

2011-06-18 Thread Thiago A . Corrêa
Hi,
Sorry for the crossposting if you also subscribe kernel-arm. I
only found this list later, and I guess it would be a better place to
ask. The following message was posted to kernel-arm, but unfortunally
I'm still looking for help on this problem.

I'm using the mini2416 [1] and it has a SMC LAN9221 chip
connected to CS2 that I'm trying to use with mainline kernel. I'm
patching the kernel, using their very old kernel as reference, but so
far I haven't been able to get the kernel to detect the chip. It looks
like it won't even probe for it. Could someone give me some advice?
Please take a look at my patch below.

[1] http://www.armdesigner.com/MINI2416.html

diff -Naur linux-2.6.38-orig//arch/arm/mach-s3c2416/mach-smdk2416.c
linux-2.6.38/arch/arm/mach-s3c2416/mach-smdk2416.c
--- linux-2.6.38-orig//arch/arm/mach-s3c2416/mach-smdk2416.c2011-03-14
22:20:32.0 -0300
+++ linux-2.6.38/arch/arm/mach-s3c2416/mach-smdk2416.c  2011-06-09
18:32:10.0 -0300
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -53,9 +54,11 @@

 #include 

+#define S3C_PA_SMC9115 (0x0800)
+
 static struct map_desc smdk2416_iodesc[] __initdata = {
   /* ISA IO Space map (memory space selected by A24) */
-
+/*
   {
   .virtual= (u32)S3C24XX_VA_ISA_WORD,
   .pfn= __phys_to_pfn(S3C2410_CS2),
@@ -76,7 +79,7 @@
   .pfn= __phys_to_pfn(S3C2410_CS2 + (1<<24)),
   .length = SZ_4M,
   .type   = MT_DEVICE,
-   }
+   } */
 };

 #define UCON (S3C2410_UCON_DEFAULT | \
@@ -179,6 +182,26 @@
   .cd_type= S3C_SDHCI_CD_NONE,
 };

+static struct resource s3c_smc911x_resources[] = {
+   [0] = {
+   .start  = S3C_PA_SMC9115,
+   .end= S3C_PA_SMC9115 + 0x1fff,
+   .flags  = IORESOURCE_MEM,
+   },
+   [1] = {
+   .start  = IRQ_EINT4,
+   .end= IRQ_EINT4,
+   .flags  = IORESOURCE_IRQ,
+   },
+};
+
+static struct platform_device s3c_device_smc911x = {
+   .name   = "smc911x",
+   .id = -1,
+   .num_resources  = ARRAY_SIZE(s3c_smc911x_resources),
+   .resource   = s3c_smc911x_resources,
+};
+
 static struct platform_device *smdk2416_devices[] __initdata = {
   &s3c_device_fb,
   &s3c_device_wdt,
@@ -186,6 +209,7 @@
   &s3c_device_i2c0,
   &s3c_device_hsmmc0,
   &s3c_device_hsmmc1,
+   &s3c_device_smc911x,
 };

 static void __init smdk2416_map_io(void)
@@ -195,8 +219,58 @@
   s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
 }

+static void smdk2416_cx89x0_set(void)
+{
+   u32 val;
+
+   val = readl(S3C_BANK_CFG);
+   val &= ~(1<<8)|(1<<9)|(1<<10);
+   writel(val, S3C_BANK_CFG);
+
+   /* Bank1 Idle cycle ctrl. */
+   writel(0xf, S3C_SSMC_SMBIDCYR1);
+
+   /* Bank1 Read Wait State cont. = 14 clk  Tacc? */
+   writel(12, S3C_SSMC_SMBWSTRDR1);
+
+   /* Bank1 Write Wait State ctrl. */
+   writel(12, S3C_SSMC_SMBWSTWRR1);
+
+   /* Bank1 Output Enable Assertion Delay ctrl. Tcho? */
+   writel(2, S3C_SSMC_SMBWSTOENR1);
+
+   /* Bank1 Write Enable Assertion Delay ctrl. */
+   writel(2, S3C_SSMC_SMBWSTWENR1);
+
+   /* SMWAIT active High, Read Byte Lane Enabl  WS1? */
+   val = readl(S3C_SSMC_SMBCR1);
+
+   val |=  ((1<<15)|(1<<7));
+   writel(val, S3C_SSMC_SMBCR1);
+
+   val = readl(S3C_SSMC_SMBCR1);
+   val |=  ((1<<2)|(1<<0));
+   writel(val, S3C_SSMC_SMBCR1);
+
+   val = readl(S3C_SSMC_SMBCR1);
+   val &= ~((3<<20)|(3<<12));
+   writel(val, S3C_SSMC_SMBCR1);
+
+   val = readl(S3C_SSMC_SMBCR1);
+   val &= ~(3<<4);
+   writel(val, S3C_SSMC_SMBCR1);
+
+   val = readl(S3C_SSMC_SMBCR1);
+   val |= (1<<4);
+
+   writel(val, S3C_SSMC_SMBCR1);
+
+}
+
 static void __init smdk2416_machine_init(void)
 {
+   smdk2416_cx89x0_set();
+
   s3c_i2c0_set_platdata(NULL);
   s3c_fb_set_platdata(&smdk2416_fb_platdata);

diff -Naur linux-2.6.38-orig//arch/arm/mach-s3c2416/s3c2416.c
linux-2.6.38/arch/arm/mach-s3c2416/s3c2416.c
--- linux-2.6.38-orig//arch/arm/mach-s3c2416/s3c2416.c  2011-03-14
22:20:32.0 -0300
+++ linux-2.6.38/arch/arm/mach-s3c2416/s3c2416.c2011-06-01
21:59:50.0 -0300
@@ -63,6 +63,8 @@
   IODESC_ENT(WATCHDOG),
   IODESC_ENT(CLKPWR),
   IODESC_ENT(TIMER),
+   IODESC_ENT(EBI),
+   IODESC_ENT(SROMC),
 };

 struct sysdev_class s3c2416_sysclass = {
diff -Naur linux-2.6.38-orig//arch/arm/plat-s3c24xx/devs.c
linux-2.6.38/arch/arm/plat-s3c24xx/devs.c
--- linux-2.6.38-orig//arch/arm/plat-s3c24xx/devs.c 2011-03-14
22:20:32.0 -0300
+++ linux-2.6.38/arch/arm/plat-s3c24xx/devs.c   2011-05-26
02:42:12.0 -0300
@@ -509,3 +509,4 @@
 EXPORT_SYMBOL(s3c2412_device_iis);

 #endif // CONFIG_CPU_

Re: [PATCH V2 2/4] ASoC: SAMSUNG: Add I2S0 internal dma driver

2011-06-18 Thread Jassi Brar
On Wed, Jun 15, 2011 at 2:13 PM, Sangbeom Kim  wrote:

> +       .channels_min = 2,
> +       .channels_max = 2,
> +       .buffer_bytes_max = MAX_IDMA_BUFFER,
> +       .period_bytes_min = 128,
> +       .period_bytes_max = MAX_IDMA_PERIOD,
> +       .periods_min = 1,
> +       .periods_max = 2,
> +};
The settings here don't ensure ring buffer is always MAX_IDMA_BUFFER.
Whereas you assume that in 'iis_irq'.


> +
> +void i2sdma_getpos(dma_addr_t *src, struct snd_pcm_substream *substream)
> +{
> +       struct idma_ctrl *prtd = substream->runtime->private_data;
> +
> +       if (prtd && (prtd->state & ST_RUNNING))
> +               *src = idma.lp_tx_addr +
> +                       (readl(idma.regs + I2STRNCNT) & 0xff) * 4;
> +       else
> +               *src = idma.lp_tx_addr;
> +}
Why do we need this function ?


> +
> +static int idma_hw_params(struct snd_pcm_substream *substream,
> +                               struct snd_pcm_hw_params *params)
> +{
> +       struct snd_pcm_runtime *runtime = substream->runtime;
> +       struct idma_ctrl *prtd = substream->runtime->private_data;
> +
> +       dev_dbg(dev, "Entered %s\n", __func__);
> +
> +       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
> +       runtime->dma_bytes = params_buffer_bytes(params);
> +
> +       prtd->start = prtd->pos = runtime->dma_addr;
> +       prtd->period = params_periods(params);
> +       prtd->periodsz = params_period_bytes(params);
> +       prtd->end = idma.lp_tx_addr + runtime->dma_bytes;
 prtd->end = runtime->dma_addr + runtime->dma_bytes;   makes better sense


> +static snd_pcm_uframes_t
> +       idma_pointer(struct snd_pcm_substream *substream)
> +{
> +       struct snd_pcm_runtime *runtime = substream->runtime;
> +       struct idma_ctrl *prtd = runtime->private_data;
> +       dma_addr_t src;
> +       unsigned long res;
> +
> +       dev_dbg(dev, "Entered %s\n", __func__);
> +
> +       spin_lock(&prtd->lock);
> +
> +       idma_getpos(&src);
> +       res = src - prtd->start;
> +
> +       spin_unlock(&prtd->lock);
> +
> +       dev_dbg(dev, "Pointer %x \n", src);
> +
> +       if (res >= snd_pcm_lib_buffer_bytes(substream)) {
> +               if (res == snd_pcm_lib_buffer_bytes(substream))
This second check is redundant.


+static irqreturn_t iis_irq(int irqno, void *dev_id)
+{
+   struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id;
+   u32 iiscon, iisahb, val, addr;
+
+   iisahb  = readl(idma.regs + I2SAHB);
+   iiscon  = readl(idma.regs + I2SCON);
+
+   val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0;
+
+   if (val) {
+   iisahb |= val;
+   writel(iisahb, idma.regs + I2SAHB);
+
+   addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr;
+   addr += prtd->period;
+   addr %= MAX_IDMA_BUFFER;
+   addr += idma.lp_tx_addr;
+
+   writel(addr, idma.regs + I2SLVL0ADDR);
+
+   if (prtd->cb) {
+   if (iisahb & AHB_LVL0INT)
   iisahb will always have the AHB_LVL0INT bit set at this point.


> +void idma_reg_init(void *regs)
> +{
> +       spin_lock_init(&idma.lock);
> +       idma.regs = regs;
> +}
> +
Why initialize lock twice, here ...

> +void idma_addr_init(dma_addr_t addr)
> +{
> +       spin_lock_init(&idma.lock);
> +       idma.lp_tx_addr = addr;
> +}
... and here.
And we might have races here - there is no mechanism to ensure these
functions are called before idma.lp_tx_addr and idma.regs are used.
Also, please try to merge them into one function.


> +MODULE_DESCRIPTION("Samsung ASoC IDMA Driver");
> +MODULE_LICENSE("GPL");
The MODULE_AUTHOR field is missing here.


Thnx,
-j
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2 1/4] ASoC: SAMSUNG: Modify I2S driver to support idma

2011-06-18 Thread Jassi Brar
On Wed, Jun 15, 2011 at 2:13 PM, Sangbeom Kim  wrote:

> +#define AHB_INTENLVL0          (1 << 24)
> +#define AHB_LVL0INT            (1 << 20)
> +#define AHB_CLRLVL0INT         (1 << 16)
> +#define AHB_DMARLD             (1 << 5)
> +#define AHB_INTMASK            (1 << 3)
> +#define AHB_DMAEN              (1 << 0)
> +#define AHB_LVLINTMASK         (0xf << 20)
> +
> +#define I2SSIZE_TRNMSK         (0x)
> +#define I2SSIZE_SHIFT          (16)
Not serious but 
a) Let us please get over our infatuation with such parentheses :)
b) Ideally these _new_ definitions should have been added separate to
this moving.


> diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
> index 992a732..2fc2428 100644
> --- a/sound/soc/samsung/i2s.c
> +++ b/sound/soc/samsung/i2s.c
> @@ -9,7 +9,7 @@
>  * it under the terms of the GNU General Public License version 2 as
>  * published by the Free Software Foundation.
>  */
> -
> +#define DEBUG
Usually we don't do it by default.


> +#define ST_RUNNING             (1<<0)
> +#define ST_OPENED              (1<<1)
why do we need these two defines ?


 @@ -646,6 +548,7 @@ static int i2s_hw_params(struct snd_pcm_substream
*substream,
>  {
>        struct i2s_dai *i2s = to_info(dai);
>        u32 mod = readl(i2s->addr + I2SMOD);
> +       u32 ahb = readl(i2s->addr + I2SAHB);
Please realize that this function is common for even s3c24xx, for
which this is invalid AHB read
and all other subsequent ops.

> @@ -702,6 +605,13 @@ static int i2s_hw_params(struct snd_pcm_substream 
> *substream,
>                                params_format(params));
>                return -EINVAL;
>        }
> +
> +       if (is_secondary(i2s)) {
> +               ahb |= (AHB_DMARLD | AHB_INTMASK);
> +               mod |= MOD_TXS_IDMA;
> +       }
> +
> +       writel(ahb, i2s->addr + I2SAHB);
... this too.
--
To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html