LAN9221 with Samsumg S3C2416
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
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
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