1 /* 2 * Copyright (C) ST-Ericsson SA 2012 3 * 4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>, 5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com> 6 * for ST-Ericsson. 7 * 8 * License terms: 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as published 12 * by the Free Software Foundation. 13 */ 14 15 #include <linux/module.h> 16 #include <linux/device.h> 17 #include <linux/io.h> 18 #include <linux/clk.h> 19 #include <linux/mutex.h> 20 21 #include <sound/soc.h> 22 #include <sound/soc-dapm.h> 23 #include <sound/pcm.h> 24 #include <sound/pcm_params.h> 25 26 #include "ux500_pcm.h" 27 #include "ux500_msp_dai.h" 28 #include "mop500_ab8500.h" 29 #include "../codecs/ab8500-codec.h" 30 31 #define TX_SLOT_MONO 0x0008 32 #define TX_SLOT_STEREO 0x000a 33 #define RX_SLOT_MONO 0x0001 34 #define RX_SLOT_STEREO 0x0003 35 #define TX_SLOT_8CH 0x00FF 36 #define RX_SLOT_8CH 0x00FF 37 38 #define DEF_TX_SLOTS TX_SLOT_STEREO 39 #define DEF_RX_SLOTS RX_SLOT_MONO 40 41 #define DRIVERMODE_NORMAL 0 42 #define DRIVERMODE_CODEC_ONLY 1 43 44 /* Slot configuration */ 45 static unsigned int tx_slots = DEF_TX_SLOTS; 46 static unsigned int rx_slots = DEF_RX_SLOTS; 47 48 /* Configuration consistency parameters */ 49 static DEFINE_MUTEX(mop500_ab8500_params_lock); 50 static unsigned long mop500_ab8500_usage; 51 static int mop500_ab8500_rate; 52 static int mop500_ab8500_channels; 53 54 /* Clocks */ 55 static const char * const enum_mclk[] = { 56 "SYSCLK", 57 "ULPCLK" 58 }; 59 enum mclk { 60 MCLK_SYSCLK, 61 MCLK_ULPCLK, 62 }; 63 64 static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk); 65 66 /* Private data for machine-part MOP500<->AB8500 */ 67 struct mop500_ab8500_drvdata { 68 /* Clocks */ 69 enum mclk mclk_sel; 70 struct clk *clk_ptr_intclk; 71 struct clk *clk_ptr_sysclk; 72 struct clk *clk_ptr_ulpclk; 73 }; 74 75 static inline const char *get_mclk_str(enum mclk mclk_sel) 76 { 77 switch (mclk_sel) { 78 case MCLK_SYSCLK: 79 return "SYSCLK"; 80 case MCLK_ULPCLK: 81 return "ULPCLK"; 82 default: 83 return "Unknown"; 84 } 85 } 86 87 static int mop500_ab8500_set_mclk(struct device *dev, 88 struct mop500_ab8500_drvdata *drvdata) 89 { 90 int status; 91 struct clk *clk_ptr; 92 93 if (IS_ERR(drvdata->clk_ptr_intclk)) { 94 dev_err(dev, 95 "%s: ERROR: intclk not initialized!\n", __func__); 96 return -EIO; 97 } 98 99 switch (drvdata->mclk_sel) { 100 case MCLK_SYSCLK: 101 clk_ptr = drvdata->clk_ptr_sysclk; 102 break; 103 case MCLK_ULPCLK: 104 clk_ptr = drvdata->clk_ptr_ulpclk; 105 break; 106 default: 107 return -EINVAL; 108 } 109 110 if (IS_ERR(clk_ptr)) { 111 dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__, 112 get_mclk_str(drvdata->mclk_sel)); 113 return -EIO; 114 } 115 116 status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr); 117 if (status) 118 dev_err(dev, 119 "%s: ERROR: Setting intclk parent to %s failed (ret = %d)!", 120 __func__, get_mclk_str(drvdata->mclk_sel), status); 121 else 122 dev_dbg(dev, 123 "%s: intclk parent changed to %s.\n", 124 __func__, get_mclk_str(drvdata->mclk_sel)); 125 126 return status; 127 } 128 129 /* 130 * Control-events 131 */ 132 133 static int mclk_input_control_get(struct snd_kcontrol *kcontrol, 134 struct snd_ctl_elem_value *ucontrol) 135 { 136 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 137 struct mop500_ab8500_drvdata *drvdata = 138 snd_soc_card_get_drvdata(card); 139 140 ucontrol->value.enumerated.item[0] = drvdata->mclk_sel; 141 142 return 0; 143 } 144 145 static int mclk_input_control_put(struct snd_kcontrol *kcontrol, 146 struct snd_ctl_elem_value *ucontrol) 147 { 148 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 149 struct mop500_ab8500_drvdata *drvdata = 150 snd_soc_card_get_drvdata(card); 151 unsigned int val = ucontrol->value.enumerated.item[0]; 152 153 if (val > (unsigned int)MCLK_ULPCLK) 154 return -EINVAL; 155 if (drvdata->mclk_sel == val) 156 return 0; 157 158 drvdata->mclk_sel = val; 159 160 return 1; 161 } 162 163 /* 164 * Controls 165 */ 166 167 static struct snd_kcontrol_new mop500_ab8500_ctrls[] = { 168 SOC_ENUM_EXT("Master Clock Select", 169 soc_enum_mclk, 170 mclk_input_control_get, mclk_input_control_put), 171 SOC_DAPM_PIN_SWITCH("Headset Left"), 172 SOC_DAPM_PIN_SWITCH("Headset Right"), 173 SOC_DAPM_PIN_SWITCH("Earpiece"), 174 SOC_DAPM_PIN_SWITCH("Speaker Left"), 175 SOC_DAPM_PIN_SWITCH("Speaker Right"), 176 SOC_DAPM_PIN_SWITCH("LineOut Left"), 177 SOC_DAPM_PIN_SWITCH("LineOut Right"), 178 SOC_DAPM_PIN_SWITCH("Vibra 1"), 179 SOC_DAPM_PIN_SWITCH("Vibra 2"), 180 SOC_DAPM_PIN_SWITCH("Mic 1"), 181 SOC_DAPM_PIN_SWITCH("Mic 2"), 182 SOC_DAPM_PIN_SWITCH("LineIn Left"), 183 SOC_DAPM_PIN_SWITCH("LineIn Right"), 184 SOC_DAPM_PIN_SWITCH("DMic 1"), 185 SOC_DAPM_PIN_SWITCH("DMic 2"), 186 SOC_DAPM_PIN_SWITCH("DMic 3"), 187 SOC_DAPM_PIN_SWITCH("DMic 4"), 188 SOC_DAPM_PIN_SWITCH("DMic 5"), 189 SOC_DAPM_PIN_SWITCH("DMic 6"), 190 }; 191 192 /* ASoC */ 193 194 static int mop500_ab8500_startup(struct snd_pcm_substream *substream) 195 { 196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 197 198 /* Set audio-clock source */ 199 return mop500_ab8500_set_mclk(rtd->card->dev, 200 snd_soc_card_get_drvdata(rtd->card)); 201 } 202 203 static void mop500_ab8500_shutdown(struct snd_pcm_substream *substream) 204 { 205 struct snd_soc_pcm_runtime *rtd = substream->private_data; 206 struct device *dev = rtd->card->dev; 207 208 dev_dbg(dev, "%s: Enter\n", __func__); 209 210 /* Reset slots configuration to default(s) */ 211 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 212 tx_slots = DEF_TX_SLOTS; 213 else 214 rx_slots = DEF_RX_SLOTS; 215 } 216 217 static int mop500_ab8500_hw_params(struct snd_pcm_substream *substream, 218 struct snd_pcm_hw_params *params) 219 { 220 struct snd_soc_pcm_runtime *rtd = substream->private_data; 221 struct snd_soc_dai *codec_dai = rtd->codec_dai; 222 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 223 struct device *dev = rtd->card->dev; 224 unsigned int fmt; 225 int channels, ret = 0, driver_mode, slots; 226 unsigned int sw_codec, sw_cpu; 227 bool is_playback; 228 229 dev_dbg(dev, "%s: Enter\n", __func__); 230 231 dev_dbg(dev, "%s: substream->pcm->name = %s\n" 232 "substream->pcm->id = %s.\n" 233 "substream->name = %s.\n" 234 "substream->number = %d.\n", 235 __func__, 236 substream->pcm->name, 237 substream->pcm->id, 238 substream->name, 239 substream->number); 240 241 /* Ensure configuration consistency between DAIs */ 242 mutex_lock(&mop500_ab8500_params_lock); 243 if (mop500_ab8500_usage) { 244 if (mop500_ab8500_rate != params_rate(params) || 245 mop500_ab8500_channels != params_channels(params)) { 246 mutex_unlock(&mop500_ab8500_params_lock); 247 return -EBUSY; 248 } 249 } else { 250 mop500_ab8500_rate = params_rate(params); 251 mop500_ab8500_channels = params_channels(params); 252 } 253 __set_bit(cpu_dai->id, &mop500_ab8500_usage); 254 mutex_unlock(&mop500_ab8500_params_lock); 255 256 channels = params_channels(params); 257 258 switch (params_format(params)) { 259 case SNDRV_PCM_FORMAT_S32_LE: 260 sw_cpu = 32; 261 break; 262 263 case SNDRV_PCM_FORMAT_S16_LE: 264 sw_cpu = 16; 265 break; 266 267 default: 268 return -EINVAL; 269 } 270 271 /* Setup codec depending on driver-mode */ 272 if (channels == 8) 273 driver_mode = DRIVERMODE_CODEC_ONLY; 274 else 275 driver_mode = DRIVERMODE_NORMAL; 276 dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__, 277 (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY"); 278 279 /* Setup format */ 280 281 if (driver_mode == DRIVERMODE_NORMAL) { 282 fmt = SND_SOC_DAIFMT_DSP_A | 283 SND_SOC_DAIFMT_CBM_CFM | 284 SND_SOC_DAIFMT_NB_NF | 285 SND_SOC_DAIFMT_CONT; 286 } else { 287 fmt = SND_SOC_DAIFMT_DSP_A | 288 SND_SOC_DAIFMT_CBM_CFM | 289 SND_SOC_DAIFMT_NB_NF | 290 SND_SOC_DAIFMT_GATED; 291 } 292 293 ret = snd_soc_dai_set_fmt(codec_dai, fmt); 294 if (ret < 0) { 295 dev_err(dev, 296 "%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n", 297 __func__, ret); 298 return ret; 299 } 300 301 ret = snd_soc_dai_set_fmt(cpu_dai, fmt); 302 if (ret < 0) { 303 dev_err(dev, 304 "%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n", 305 __func__, ret); 306 return ret; 307 } 308 309 /* Setup TDM-slots */ 310 311 is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 312 switch (channels) { 313 case 1: 314 slots = 16; 315 tx_slots = (is_playback) ? TX_SLOT_MONO : 0; 316 rx_slots = (is_playback) ? 0 : RX_SLOT_MONO; 317 break; 318 case 2: 319 slots = 16; 320 tx_slots = (is_playback) ? TX_SLOT_STEREO : 0; 321 rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO; 322 break; 323 case 8: 324 slots = 16; 325 tx_slots = (is_playback) ? TX_SLOT_8CH : 0; 326 rx_slots = (is_playback) ? 0 : RX_SLOT_8CH; 327 break; 328 default: 329 return -EINVAL; 330 } 331 332 if (driver_mode == DRIVERMODE_NORMAL) 333 sw_codec = sw_cpu; 334 else 335 sw_codec = 20; 336 337 dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, 338 tx_slots, rx_slots); 339 ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots, 340 sw_cpu); 341 if (ret) 342 return ret; 343 344 dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__, 345 tx_slots, rx_slots); 346 ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots, 347 sw_codec); 348 if (ret) 349 return ret; 350 351 return 0; 352 } 353 354 static int mop500_ab8500_hw_free(struct snd_pcm_substream *substream) 355 { 356 struct snd_soc_pcm_runtime *rtd = substream->private_data; 357 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 358 359 mutex_lock(&mop500_ab8500_params_lock); 360 __clear_bit(cpu_dai->id, &mop500_ab8500_usage); 361 mutex_unlock(&mop500_ab8500_params_lock); 362 363 return 0; 364 } 365 366 struct snd_soc_ops mop500_ab8500_ops[] = { 367 { 368 .hw_params = mop500_ab8500_hw_params, 369 .hw_free = mop500_ab8500_hw_free, 370 .startup = mop500_ab8500_startup, 371 .shutdown = mop500_ab8500_shutdown, 372 } 373 }; 374 375 int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) 376 { 377 struct snd_soc_codec *codec = rtd->codec; 378 struct device *dev = rtd->card->dev; 379 struct mop500_ab8500_drvdata *drvdata; 380 int ret; 381 382 dev_dbg(dev, "%s Enter.\n", __func__); 383 384 /* Create driver private-data struct */ 385 drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata), 386 GFP_KERNEL); 387 snd_soc_card_set_drvdata(rtd->card, drvdata); 388 389 /* Setup clocks */ 390 391 drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk"); 392 if (IS_ERR(drvdata->clk_ptr_sysclk)) 393 dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n", 394 __func__); 395 drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk"); 396 if (IS_ERR(drvdata->clk_ptr_ulpclk)) 397 dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n", 398 __func__); 399 drvdata->clk_ptr_intclk = clk_get(dev, "intclk"); 400 if (IS_ERR(drvdata->clk_ptr_intclk)) 401 dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n", 402 __func__); 403 404 /* Set intclk default parent to ulpclk */ 405 drvdata->mclk_sel = MCLK_ULPCLK; 406 ret = mop500_ab8500_set_mclk(dev, drvdata); 407 if (ret < 0) 408 dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n", 409 __func__); 410 411 drvdata->mclk_sel = MCLK_ULPCLK; 412 413 /* Add controls */ 414 ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls, 415 ARRAY_SIZE(mop500_ab8500_ctrls)); 416 if (ret < 0) { 417 pr_err("%s: Failed to add machine-controls (%d)!\n", 418 __func__, ret); 419 return ret; 420 } 421 422 ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece"); 423 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left"); 424 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right"); 425 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left"); 426 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right"); 427 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1"); 428 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2"); 429 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1"); 430 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2"); 431 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left"); 432 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right"); 433 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1"); 434 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2"); 435 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3"); 436 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4"); 437 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5"); 438 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6"); 439 440 return ret; 441 } 442 443 void mop500_ab8500_remove(struct snd_soc_card *card) 444 { 445 struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card); 446 447 if (drvdata->clk_ptr_sysclk != NULL) 448 clk_put(drvdata->clk_ptr_sysclk); 449 if (drvdata->clk_ptr_ulpclk != NULL) 450 clk_put(drvdata->clk_ptr_ulpclk); 451 if (drvdata->clk_ptr_intclk != NULL) 452 clk_put(drvdata->clk_ptr_intclk); 453 454 snd_soc_card_set_drvdata(card, drvdata); 455 } 456