| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 1 | /* | 
 | 2 |  * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2008 Bluewater Systems Ltd | 
 | 5 |  * Author: Ryan Mallon <ryan@bluewatersys.com> | 
 | 6 |  * | 
 | 7 |  *  This program is free software; you can redistribute  it and/or modify it | 
 | 8 |  *  under  the terms of  the GNU General  Public License as published by the | 
 | 9 |  *  Free Software Foundation;  either version 2 of the  License, or (at your | 
 | 10 |  *  option) any later version. | 
 | 11 |  * | 
 | 12 |  */ | 
 | 13 |  | 
 | 14 | #include <linux/platform_device.h> | 
 | 15 | #include <sound/core.h> | 
 | 16 | #include <sound/pcm.h> | 
 | 17 | #include <sound/soc.h> | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 18 |  | 
 | 19 | #include <asm/mach-types.h> | 
 | 20 | #include <mach/hardware.h> | 
 | 21 |  | 
 | 22 | #include "../codecs/tlv320aic23.h" | 
 | 23 | #include "ep93xx-pcm.h" | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 24 |  | 
 | 25 | #define CODEC_CLOCK 5644800 | 
 | 26 |  | 
 | 27 | static int snappercl15_hw_params(struct snd_pcm_substream *substream, | 
 | 28 | 				 struct snd_pcm_hw_params *params) | 
 | 29 | { | 
 | 30 | 	struct snd_soc_pcm_runtime *rtd = substream->private_data; | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 31 | 	struct snd_soc_dai *codec_dai = rtd->codec_dai; | 
 | 32 | 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 33 | 	int err; | 
 | 34 |  | 
 | 35 | 	err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | 
 | 36 | 				  SND_SOC_DAIFMT_NB_IF | | 
 | 37 | 				  SND_SOC_DAIFMT_CBS_CFS); | 
 | 38 |  | 
 | 39 | 	err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |  | 
 | 40 | 				  SND_SOC_DAIFMT_NB_IF |		   | 
 | 41 | 				  SND_SOC_DAIFMT_CBS_CFS); | 
 | 42 | 	if (err) | 
 | 43 | 		return err; | 
 | 44 |  | 
 | 45 | 	err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK,  | 
 | 46 | 				     SND_SOC_CLOCK_IN); | 
 | 47 | 	if (err) | 
 | 48 | 		return err; | 
 | 49 |  | 
 | 50 | 	err = snd_soc_dai_set_sysclk(cpu_dai, 0, CODEC_CLOCK,  | 
 | 51 | 				     SND_SOC_CLOCK_OUT); | 
 | 52 | 	if (err) | 
 | 53 | 		return err; | 
 | 54 |  | 
 | 55 | 	return 0; | 
 | 56 | } | 
 | 57 |  | 
 | 58 | static struct snd_soc_ops snappercl15_ops = { | 
 | 59 | 	.hw_params	= snappercl15_hw_params, | 
 | 60 | }; | 
 | 61 |  | 
 | 62 | static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { | 
 | 63 | 	SND_SOC_DAPM_HP("Headphone Jack", NULL), | 
 | 64 | 	SND_SOC_DAPM_LINE("Line In", NULL), | 
 | 65 | 	SND_SOC_DAPM_MIC("Mic Jack", NULL), | 
 | 66 | }; | 
 | 67 |  | 
 | 68 | static const struct snd_soc_dapm_route audio_map[] = { | 
 | 69 | 	{"Headphone Jack", NULL, "LHPOUT"}, | 
 | 70 | 	{"Headphone Jack", NULL, "RHPOUT"}, | 
 | 71 |  | 
 | 72 | 	{"LLINEIN", NULL, "Line In"}, | 
 | 73 | 	{"RLINEIN", NULL, "Line In"}, | 
 | 74 |  | 
 | 75 | 	{"MICIN", NULL, "Mic Jack"}, | 
 | 76 | }; | 
 | 77 |  | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 78 | static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 79 | { | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 80 | 	struct snd_soc_codec *codec = rtd->codec; | 
| Liam Girdwood | ce6120c | 2010-11-05 15:53:46 +0200 | [diff] [blame] | 81 | 	struct snd_soc_dapm_context *dapm = &codec->dapm; | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 82 |  | 
| Liam Girdwood | ce6120c | 2010-11-05 15:53:46 +0200 | [diff] [blame] | 83 | 	snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 84 | 				  ARRAY_SIZE(tlv320aic23_dapm_widgets)); | 
 | 85 |  | 
| Liam Girdwood | ce6120c | 2010-11-05 15:53:46 +0200 | [diff] [blame] | 86 | 	snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 87 | 	return 0; | 
 | 88 | } | 
 | 89 |  | 
 | 90 | static struct snd_soc_dai_link snappercl15_dai = { | 
 | 91 | 	.name		= "tlv320aic23", | 
 | 92 | 	.stream_name	= "AIC23", | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 93 | 	.cpu_dai_name	= "ep93xx-i2s", | 
 | 94 | 	.codec_dai_name	= "tlv320aic23-hifi", | 
 | 95 | 	.codec_name	= "tlv320aic23-codec.0-001a", | 
 | 96 | 	.platform_name	=  "ep93xx-pcm-audio", | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 97 | 	.init		= snappercl15_tlv320aic23_init, | 
 | 98 | 	.ops		= &snappercl15_ops, | 
 | 99 | }; | 
 | 100 |  | 
 | 101 | static struct snd_soc_card snd_soc_snappercl15 = { | 
 | 102 | 	.name		= "Snapper CL15", | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 103 | 	.dai_link	= &snappercl15_dai, | 
 | 104 | 	.num_links	= 1, | 
 | 105 | }; | 
 | 106 |  | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 107 | static struct platform_device *snappercl15_snd_device; | 
 | 108 |  | 
 | 109 | static int __init snappercl15_init(void) | 
 | 110 | { | 
 | 111 | 	int ret; | 
 | 112 |  | 
 | 113 | 	if (!machine_is_snapper_cl15()) | 
 | 114 | 		return -ENODEV; | 
 | 115 |  | 
 | 116 | 	ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, | 
 | 117 | 				 EP93XX_SYSCON_I2SCLKDIV_ORIDE | | 
 | 118 | 				 EP93XX_SYSCON_I2SCLKDIV_SPOL); | 
 | 119 | 	if (ret) | 
 | 120 | 		return ret; | 
 | 121 |  | 
 | 122 | 	snappercl15_snd_device = platform_device_alloc("soc-audio", -1); | 
 | 123 | 	if (!snappercl15_snd_device) | 
 | 124 | 		return -ENOMEM; | 
 | 125 | 	 | 
| Liam Girdwood | f0fba2a | 2010-03-17 20:15:21 +0000 | [diff] [blame] | 126 | 	platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); | 
| Ryan Mallon | 315f7da | 2010-06-08 22:01:12 +1200 | [diff] [blame] | 127 | 	ret = platform_device_add(snappercl15_snd_device); | 
 | 128 | 	if (ret) | 
 | 129 | 		platform_device_put(snappercl15_snd_device); | 
 | 130 |  | 
 | 131 | 	return ret; | 
 | 132 | } | 
 | 133 |  | 
 | 134 | static void __exit snappercl15_exit(void) | 
 | 135 | { | 
 | 136 | 	platform_device_unregister(snappercl15_snd_device); | 
 | 137 | 	ep93xx_i2s_release(); | 
 | 138 | } | 
 | 139 |  | 
 | 140 | module_init(snappercl15_init); | 
 | 141 | module_exit(snappercl15_exit); | 
 | 142 |  | 
 | 143 | MODULE_AUTHOR("Ryan Mallon <ryan@bluewatersys.com>"); | 
 | 144 | MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); | 
 | 145 | MODULE_LICENSE("GPL"); | 
 | 146 |  |