| OLD | NEW |
| 1 /* | 1 /* |
| 2 * ALSA SoC WL1273 codec driver | 2 * ALSA SoC WL1273 codec driver |
| 3 * | 3 * |
| 4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com> | 4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com> |
| 5 * | 5 * |
| 6 * Copyright: (C) 2010 Nokia Corporation | 6 * Copyright: (C) 2010 Nokia Corporation |
| 7 * | 7 * |
| 8 * This program is free software; you can redistribute it and/or | 8 * This program is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU General Public License | 9 * modify it under the terms of the GNU General Public License |
| 10 * version 2 as published by the Free Software Foundation. | 10 * version 2 as published by the Free Software Foundation. |
| 11 * | 11 * |
| 12 * This program is distributed in the hope that it will be useful, but | 12 * This program is distributed in the hope that it will be useful, but |
| 13 * WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 * General Public License for more details. | 15 * General Public License for more details. |
| 16 * | 16 * |
| 17 * You should have received a copy of the GNU General Public License | 17 * You should have received a copy of the GNU General Public License |
| 18 * along with this program; if not, write to the Free Software | 18 * along with this program; if not, write to the Free Software |
| 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA |
| 20 * 02110-1301 USA | 20 * 02110-1301 USA |
| 21 * | 21 * |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include <linux/mfd/wl1273-core.h> | 24 #include <linux/mfd/wl1273-core.h> |
| 25 #include <linux/slab.h> | 25 #include <linux/slab.h> |
| 26 #include <sound/pcm.h> | 26 #include <sound/pcm.h> |
| 27 #include <sound/pcm_params.h> | 27 #include <sound/pcm_params.h> |
| 28 #include <sound/soc-dai.h> | 28 #include <sound/soc.h> |
| 29 #include <sound/soc-dapm.h> | |
| 30 #include <sound/initval.h> | 29 #include <sound/initval.h> |
| 31 | 30 |
| 32 #include "wl1273.h" | 31 #include "wl1273.h" |
| 33 | 32 |
| 34 enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX }; | 33 enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX }; |
| 35 | 34 |
| 36 /* codec private data */ | 35 /* codec private data */ |
| 37 struct wl1273_priv { | 36 struct wl1273_priv { |
| 38 enum wl1273_mode mode; | 37 enum wl1273_mode mode; |
| 39 struct wl1273_core *core; | 38 struct wl1273_core *core; |
| 40 unsigned int channels; | 39 unsigned int channels; |
| 41 }; | 40 }; |
| 42 | 41 |
| 43 static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core, | 42 static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core, |
| 44 int rate, int width) | 43 int rate, int width) |
| 45 { | 44 { |
| 46 » struct device *dev = &core->i2c_dev->dev; | 45 » struct device *dev = &core->client->dev; |
| 47 int r = 0; | 46 int r = 0; |
| 48 u16 mode; | 47 u16 mode; |
| 49 | 48 |
| 50 dev_dbg(dev, "rate: %d\n", rate); | 49 dev_dbg(dev, "rate: %d\n", rate); |
| 51 dev_dbg(dev, "width: %d\n", width); | 50 dev_dbg(dev, "width: %d\n", width); |
| 52 | 51 |
| 53 mutex_lock(&core->lock); | 52 mutex_lock(&core->lock); |
| 54 | 53 |
| 55 mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE; | 54 mode = core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE; |
| 56 | 55 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 dev_err(dev, "Data width: %d not supported\n", width); | 116 dev_err(dev, "Data width: %d not supported\n", width); |
| 118 r = -EINVAL; | 117 r = -EINVAL; |
| 119 goto out; | 118 goto out; |
| 120 } | 119 } |
| 121 | 120 |
| 122 dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE); | 121 dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE); |
| 123 dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode); | 122 dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode); |
| 124 dev_dbg(dev, "mode: 0x%04x\n", mode); | 123 dev_dbg(dev, "mode: 0x%04x\n", mode); |
| 125 | 124 |
| 126 if (core->i2s_mode != mode) { | 125 if (core->i2s_mode != mode) { |
| 127 » » r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET, mode); | 126 » » r = core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode); |
| 128 if (r) | 127 if (r) |
| 129 goto out; | 128 goto out; |
| 130 | 129 |
| 131 core->i2s_mode = mode; | 130 core->i2s_mode = mode; |
| 132 » » r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE, | 131 » » r = core->write(core, WL1273_AUDIO_ENABLE, |
| 133 » » » » » WL1273_AUDIO_ENABLE_I2S); | 132 » » » » WL1273_AUDIO_ENABLE_I2S); |
| 134 if (r) | 133 if (r) |
| 135 goto out; | 134 goto out; |
| 136 } | 135 } |
| 137 out: | 136 out: |
| 138 mutex_unlock(&core->lock); | 137 mutex_unlock(&core->lock); |
| 139 | 138 |
| 140 return r; | 139 return r; |
| 141 } | 140 } |
| 142 | 141 |
| 143 static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core, | 142 static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core, |
| 144 int channel_number) | 143 int channel_number) |
| 145 { | 144 { |
| 146 » struct i2c_client *client = core->i2c_dev; | 145 » struct device *dev = &core->client->dev; |
| 147 » struct device *dev = &client->dev; | |
| 148 int r = 0; | 146 int r = 0; |
| 149 | 147 |
| 150 dev_dbg(dev, "%s\n", __func__); | 148 dev_dbg(dev, "%s\n", __func__); |
| 151 | 149 |
| 152 mutex_lock(&core->lock); | 150 mutex_lock(&core->lock); |
| 153 | 151 |
| 154 if (core->channel_number == channel_number) | 152 if (core->channel_number == channel_number) |
| 155 goto out; | 153 goto out; |
| 156 | 154 |
| 157 if (channel_number == 1 && core->mode == WL1273_MODE_RX) | 155 if (channel_number == 1 && core->mode == WL1273_MODE_RX) |
| 158 » » r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, | 156 » » r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO); |
| 159 » » » » » WL1273_RX_MONO); | |
| 160 else if (channel_number == 1 && core->mode == WL1273_MODE_TX) | 157 else if (channel_number == 1 && core->mode == WL1273_MODE_TX) |
| 161 » » r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, | 158 » » r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO); |
| 162 » » » » » WL1273_TX_MONO); | |
| 163 else if (channel_number == 2 && core->mode == WL1273_MODE_RX) | 159 else if (channel_number == 2 && core->mode == WL1273_MODE_RX) |
| 164 » » r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, | 160 » » r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO); |
| 165 » » » » » WL1273_RX_STEREO); | |
| 166 else if (channel_number == 2 && core->mode == WL1273_MODE_TX) | 161 else if (channel_number == 2 && core->mode == WL1273_MODE_TX) |
| 167 » » r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, | 162 » » r = core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO); |
| 168 » » » » » WL1273_TX_STEREO); | |
| 169 else | 163 else |
| 170 r = -EINVAL; | 164 r = -EINVAL; |
| 171 out: | 165 out: |
| 172 mutex_unlock(&core->lock); | 166 mutex_unlock(&core->lock); |
| 173 | 167 |
| 174 return r; | 168 return r; |
| 175 } | 169 } |
| 176 | 170 |
| 177 static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, | 171 static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, |
| 178 struct snd_ctl_elem_value *ucontrol) | 172 struct snd_ctl_elem_value *ucontrol) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 225 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 232 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 226 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
| 233 int val, r = 0; | 227 int val, r = 0; |
| 234 | 228 |
| 235 dev_dbg(codec->dev, "%s: enter.\n", __func__); | 229 dev_dbg(codec->dev, "%s: enter.\n", __func__); |
| 236 | 230 |
| 237 val = ucontrol->value.integer.value[0]; | 231 val = ucontrol->value.integer.value[0]; |
| 238 if (wl1273->core->audio_mode == val) | 232 if (wl1273->core->audio_mode == val) |
| 239 return 0; | 233 return 0; |
| 240 | 234 |
| 241 » r = wl1273_fm_set_audio(wl1273->core, val); | 235 » r = wl1273->core->set_audio(wl1273->core, val); |
| 242 if (r < 0) | 236 if (r < 0) |
| 243 return r; | 237 return r; |
| 244 | 238 |
| 245 return 1; | 239 return 1; |
| 246 } | 240 } |
| 247 | 241 |
| 248 static const char *wl1273_audio_strings[] = { "Digital", "Analog" }; | 242 static const char *wl1273_audio_strings[] = { "Digital", "Analog" }; |
| 249 | 243 |
| 250 static const struct soc_enum wl1273_audio_enum = | 244 static const struct soc_enum wl1273_audio_enum = |
| 251 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings), | 245 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 266 | 260 |
| 267 static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, | 261 static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, |
| 268 struct snd_ctl_elem_value *ucontrol) | 262 struct snd_ctl_elem_value *ucontrol) |
| 269 { | 263 { |
| 270 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 264 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 271 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 265 struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
| 272 int r; | 266 int r; |
| 273 | 267 |
| 274 dev_dbg(codec->dev, "%s: enter.\n", __func__); | 268 dev_dbg(codec->dev, "%s: enter.\n", __func__); |
| 275 | 269 |
| 276 » r = wl1273_fm_set_volume(wl1273->core, | 270 » r = wl1273->core->set_volume(wl1273->core, |
| 277 » » » » ucontrol->value.integer.value[0]); | 271 » » » » ucontrol->value.integer.value[0]); |
| 278 if (r) | 272 if (r) |
| 279 return r; | 273 return r; |
| 280 | 274 |
| 281 return 1; | 275 return 1; |
| 282 } | 276 } |
| 283 | 277 |
| 284 static const struct snd_kcontrol_new wl1273_controls[] = { | 278 static const struct snd_kcontrol_new wl1273_controls[] = { |
| 285 SOC_ENUM_EXT("Codec Mode", wl1273_enum, | 279 SOC_ENUM_EXT("Codec Mode", wl1273_enum, |
| 286 snd_wl1273_get_audio_route, snd_wl1273_set_audio_route), | 280 snd_wl1273_get_audio_route, snd_wl1273_set_audio_route), |
| 287 SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum, | 281 SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum, |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 | 513 |
| 520 static void __exit wl1273_exit(void) | 514 static void __exit wl1273_exit(void) |
| 521 { | 515 { |
| 522 platform_driver_unregister(&wl1273_platform_driver); | 516 platform_driver_unregister(&wl1273_platform_driver); |
| 523 } | 517 } |
| 524 module_exit(wl1273_exit); | 518 module_exit(wl1273_exit); |
| 525 | 519 |
| 526 MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); | 520 MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); |
| 527 MODULE_DESCRIPTION("ASoC WL1273 codec driver"); | 521 MODULE_DESCRIPTION("ASoC WL1273 codec driver"); |
| 528 MODULE_LICENSE("GPL"); | 522 MODULE_LICENSE("GPL"); |
| OLD | NEW |