I think I have my driver compiling and such with the kernel. I had an error in my last Kconfig and Makefile, which I hope I have fixed. It appears to be making correctly. I will attach the three files if anyone would like to view them. I am still working on getting linux2.6.22-rc1 booting correctly. Once I have that, I should be able to evaluate the driver a little better. I also believe I am going to need alsa-libs. I will try to locate those and get them cross-compiled asap. If anyone has pointers on my Kconfig, Makefile, or driver--or on how to get linux booting, please feel free to give them to me. Thanks. Paul
Attachment:
Kconfig
Description: Binary data
Attachment:
Makefile
Description: Binary data
/* * grh_ek_w6811 -- SoC audio for AT91SAM9260-EK board * * ASoC Codec and Machine driver for W6811 PCM interface. * * Author: Paul Kavan, Project Engineer <pkavan@xxxxxxxxx> * GRH Electronics, Inc. * Created: Jun 15, 2007 * * * Borrowed heavily from: * * eti_b1_bluecore -- SoC audio for AT91RM9200-based Endrelia ETI_B1 board * Frank Mandarino <fmandarino@xxxxxxxxxxxx> * Endrelia Technologies, 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. * */ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/version.h> #include <linux/kernel.h> #include <linux/clk.h> #include <linux/timer.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <sound/driver.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/initval.h> #include <sound/soc.h> #include <sound/soc-dapm.h> #include <asm/arch/hardware.h> #include <asm/arch/at91_pio.h> #include <asm/arch/gpio.h> #include "at91-pcm.h" #include "at91-ssc.h" #if 0 #define DBG(x...) printk(KERN_INFO "grh_ek_w6811: " x) #else #define DBG(x...) #endif /* * W6811 PCM interface codec driver. */ #define W6811_VERSION "0.1" #define W6811_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) //TODO: Check on S16_LE static struct snd_soc_codec_dai w6811_dai = { .name = "W6811", .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 1, .rates = SNDRV_PCM_RATE_8000, .formats = W6811_FORMATS,}, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 1, .rates = SNDRV_PCM_RATE_8000, .formats = W6811_FORMATS,}, }; static int w6811_soc_probe(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec; int ret = 0; printk(KERN_INFO "w6811: W6811 PCM SoC Audio %s\n", W6811_VERSION); socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); if (socdev->codec == NULL) return -ENOMEM; codec = socdev->codec; mutex_init(&codec->mutex); codec->name = "W6811"; codec->owner = THIS_MODULE; codec->dai = &w6811_dai; codec->num_dai = 1; INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_paths); /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if(ret < 0) goto err; ret = snd_soc_register_card(socdev); if (ret < 0) goto bus_err; return 0; bus_err: snd_soc_free_pcms(socdev); err: kfree(socdev->codec); socdev->codec = NULL; return ret; } static int w6811_soc_remove(struct platform_device *pdev) { struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_codec *codec = socdev->codec; if(codec == NULL) return 0; snd_soc_free_pcms(socdev); kfree(socdev->codec); return 0; } static struct snd_soc_codec_device soc_codec_dev_w6811 = { .probe = w6811_soc_probe, .remove = w6811_soc_remove, }; /* * GRH EK W6811 Machine driver. */ #define AT91_PIO_TK0 (1 << (AT91_PIN_PB16 - PIN_BASE) % 32) #define AT91_PIO_TF0 (1 << (AT91_PIN_PB17 - PIN_BASE) % 32) #define AT91_PIO_TD0 (1 << (AT91_PIN_PB18 - PIN_BASE) % 32) #define AT91_PIO_RD0 (1 << (AT91_PIN_PB19 - PIN_BASE) % 32) #define AT91_PIO_RK0 (1 << (AT91_PIN_PB20 - PIN_BASE) % 32) #define AT91_PIO_RF0 (1 << (AT91_PIN_PB21 - PIN_BASE) % 32) /* * GRH EK W6811 PCM interface machine driver operations. * * Only hw_params() is required, and only the CPU_DAI needs to be * initiailzed, as there is no real CODEC DAI. * * ??The CODEC DAI is controlled by BlueZ BCCMD and SCO operations. */ static int grh_ek_w6811_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; int ret; int cmr_div, period; /* set cpu DAI configuration */ ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* * The W6811 PCM interface sync operates at 8kHz, and * the PCM_CLK signal must be greater than 256kHz. */ cmr_div = 187; /* PCM_CLK = ~96MHz/(2*187) = 256kHz */ period = 15; /* PCM_SYNC = PCM_CLK/(2*(15+1)) = 8000Hz */ /* set the MCK divider for PCM_CLK */ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div); if (ret < 0) return ret; /* set the BCLK divider for DACLRC */ ret = cpu_dai->dai_ops.set_clkdiv(cpu_dai, AT91SSC_TCMR_PERIOD, period); if (ret < 0) return ret; return 0; } static struct snd_soc_ops grh_ek_w6811_ops = { .hw_params = grh_ek_w6811_hw_params, }; static struct snd_soc_dai_link grh_ek_w6811_dai = { .name = "W6811 PCM", .stream_name = "W6811", .cpu_dai = &at91_ssc_dai[2], //TODO: Determine what the 2 is indexing .codec_dai = &w6811_dai, .ops = &grh_ek_w6811_ops, }; static struct snd_soc_machine snd_soc_machine_grh_ek_w6811 = { .name = "GRH_EK_W6811", .dai_link = &grh_ek_w6811_dai, .num_links = 1, }; static struct snd_soc_device grh_ek_w6811_snd_devdata = { .machine = &snd_soc_machine_grh_ek_w6811, .platform = &at91_soc_platform, .codec_dev = &soc_codec_dev_w6811, }; static struct platform_device *grh_ek_w6811_snd_device; static int __init grh_ek_w6811_init(void) { int ret; u32 ssc_pio_lines; struct at91_ssc_periph *ssc = grh_ek_w6811_dai.cpu_dai->private_data; if (!request_mem_region(AT91SAM9260_BASE_SSC, SZ_16K, "soc-audio")) { DBG("SSC memory region is busy\n"); return -EBUSY; } ssc->base = ioremap(AT91SAM9260_BASE_SSC, SZ_16K); if (!ssc->base) { DBG("SSC memory ioremap failed\n"); ret = -ENOMEM; goto fail_release_mem; } ssc->pid = AT91SAM9260_ID_SSC; grh_ek_w6811_snd_device = platform_device_alloc("soc-audio", 2); //TODO: Determine why the 2 if (!grh_ek_w6811_snd_device) { DBG("platform device allocation failed\n"); ret = -ENOMEM; goto fail_io_unmap; } platform_set_drvdata(grh_ek_w6811_snd_device, &grh_ek_w6811_snd_devdata); grh_ek_w6811_snd_devdata.dev = &grh_ek_w6811_snd_device->dev; ret = platform_device_add(grh_ek_w6811_snd_device); if (ret) { DBG("platform device add failed\n"); platform_device_put(grh_ek_w6811_snd_device); goto fail_io_unmap; } //TODO: Ask Frank to make sure what is happening is what I think is happening ssc_pio_lines = AT91_PIO_TF0 | AT91_PIO_TK0 | AT91_PIO_TD0 | AT91_PIO_RD0 /* | AT91_PIO_RK0 | AT91_PIO_RF0 */; //TODO: Check on this. /* Reset all PIO registers and assign lines to peripheral A */ at91_sys_write(AT91_PIOB + PIO_PDR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_ODR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_IFDR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_CODR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_IDR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_MDDR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_PUDR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_ASR, ssc_pio_lines); at91_sys_write(AT91_PIOB + PIO_OWDR, ssc_pio_lines); printk(KERN_INFO "grh_ek_w6811: W6811 PCM in Slave Mode\n"); return ret; fail_io_unmap: iounmap(ssc->base); fail_release_mem: release_mem_region(AT91SAM9260_BASE_SSC, SZ_16K); return ret; } static void __exit grh_ek_w6811_exit(void) { struct at91_ssc_periph *ssc = grh_ek_w6811_dai.cpu_dai->private_data; platform_device_unregister(grh_ek_w6811_snd_device); iounmap(ssc->base); release_mem_region(AT91SAM9260_BASE_SSC, SZ_16K); } module_init(grh_ek_w6811_init); module_exit(grh_ek_w6811_exit); /* Module information */ MODULE_AUTHOR("Paul Kavan <pkavan@xxxxxxxxx>"); MODULE_DESCRIPTION("ALSA SoC GRH-EK-W6811"); MODULE_LICENSE("GPL");
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel