/* * sound/soc/fsl/dspeak01_fabric.c -- The ALSA glue fabric for Digispeaker dspeak01 * * Copyright 2008 Jon Smirl, Digispeaker * Author: Jon Smirl * * 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 #include "../codecs/pcm1690.h" #include "mpc5200_dma.h" #include "mpc5200_psc_i2s.h" static int dspeak01_fabric_startup(struct snd_pcm_substream *substream) { printk("dspeak01_fabric_startup\n"); return 0; } static void dspeak01_fabric_shutdown(struct snd_pcm_substream *substream) { printk("dspeak01_fabric_shutdown\n"); } static int dspeak01_fabric_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { uint rate; int ret; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; printk("dspeak01_fabric_hw_params\n"); switch (params_rate(params)) { case 11025: case 22050: case 44100: case 88200: case 176400: rate = 22579200; break; default: rate = 24576000; break; } ret = snd_soc_dai_set_sysclk(cpu_dai, MPC52xx_CLK_INTERNAL, rate, SND_SOC_CLOCK_OUT); if (ret < 0) return ret; return 0; } static int dspeak01_fabric_hw_free(struct snd_pcm_substream *substream) { printk("dspeak01_fabric_hw_free\n"); return 0; } static int dspeak01_fabric_prepare(struct snd_pcm_substream *substream) { printk("dspeak01_fabric_prepare\n"); return 0; } static int dspeak01_fabric_trigger(struct snd_pcm_substream *substream, int trigger) { printk("dspeak01_fabric_trigger\n"); return 0; } static struct snd_soc_ops dspeak01_fabric_ops = { .startup = dspeak01_fabric_startup, .shutdown = dspeak01_fabric_shutdown, .hw_params = dspeak01_fabric_hw_params, .hw_free = dspeak01_fabric_hw_free, .prepare = dspeak01_fabric_prepare, .trigger = dspeak01_fabric_trigger, }; static struct snd_soc_device device; static struct snd_soc_card card; static struct snd_soc_dai_link dspeak01_fabric_dai[] = { { .name = "I2S-0", .stream_name = "I2S-0", .codec_dai = &pcm1690_dai, .ops = &dspeak01_fabric_ops, }, { .name = "I2S-1", .stream_name = "I2S-1", .codec_dai = &pcm1690_dai, .ops = &dspeak01_fabric_ops, }, }; static int dspeak01_fabric_gpio_reset; static int dspeak01_fabric_gpio_mute; static __init int dspeak01_fabric_init_gpio(struct of_device *op, struct device_node *np, int i, int state) { int rc; int gpio; gpio = of_get_gpio(np, i); if (gpio >= 0) { rc = gpio_request(gpio, dev_name(&op->dev)); if (rc) { dev_err(&op->dev, "can't request Dspeak01 gpio #%d rc %d\n", i, rc); return rc; } gpio_direction_output(gpio, state); } else if (gpio == -EINVAL) { dev_err(&op->dev, "Dspeak01 gpio #%d is invalid\n", i); } return gpio; } static __init int dspeak01_fabric_init(void) { struct of_device *op; struct device_node *np; struct platform_device *pdev; struct i2c_client *i2c_dev; int rc; if (!machine_is_compatible("digispeaker,dspeak01")) return -ENODEV; card.platform = &mpc5200_audio_dma_platform; card.name = "Digispeaker"; card.dai_link = dspeak01_fabric_dai; dspeak01_fabric_dai[0].cpu_dai = psc_i2s_dai[0]; dspeak01_fabric_dai[1].cpu_dai = psc_i2s_dai[1]; card.num_links = ARRAY_SIZE(dspeak01_fabric_dai); device.card = &card; device.codec_dev = &pcm1690_soc_codec_dev; /* Check for the codec handle. */ op = to_of_device(psc_i2s_dai[0]->dev); np = of_parse_phandle(op->node, "codec-handle", 0); if (np) { i2c_dev = of_find_i2c_device_by_node(np); device.codec_data = i2c_get_clientdata(i2c_dev); dspeak01_fabric_gpio_reset = dspeak01_fabric_init_gpio(op, np, 0, 1); if (dspeak01_fabric_gpio_reset < 0) return dspeak01_fabric_gpio_reset; dspeak01_fabric_gpio_mute = dspeak01_fabric_init_gpio(op, np, 1, 1); if (dspeak01_fabric_gpio_mute < 0) return dspeak01_fabric_gpio_mute; } pdev = platform_device_alloc("soc-audio", 1); if (!pdev) { pr_err("dspeak01_fabric_init: platform_device_alloc() failed\n"); return -ENODEV; } platform_set_drvdata(pdev, &device); device.dev = &pdev->dev; rc = platform_device_add(pdev); if (rc) { pr_err("dspeak01_fabric_init: platform_device_add() failed\n"); return -ENODEV; } return 0; } static __exit void dspeak01_fabric_exit(void) { } module_init(dspeak01_fabric_init); module_exit(dspeak01_fabric_exit); /* Module information */ MODULE_AUTHOR("Jon Smirl"); MODULE_DESCRIPTION("ASOC Digispeaker fabric module"); MODULE_LICENSE("GPL");