inno_rk3036.c (cf40a76e7d5874bb25f4404eecc58a2e033af885) | inno_rk3036.c (40aa60a2e9ab5242593101bb6270563ee5acdf46) |
---|---|
1/* 2 * Driver of Inno codec for rk3036 by Rockchip Inc. 3 * 4 * Author: Rockchip Inc. 5 * Author: Zheng ShunQian<zhengsq@rock-chips.com> 6 */ 7 8#include <sound/soc.h> --- 182 unchanged lines hidden (view full) --- 191 {"HP Right Switch", "HP Right Out Switch", "HP Right Out"}, 192 193 {"HPL", NULL, "HP Left Switch"}, 194 {"HPR", NULL, "HP Right Switch"}, 195}; 196 197static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 198{ | 1/* 2 * Driver of Inno codec for rk3036 by Rockchip Inc. 3 * 4 * Author: Rockchip Inc. 5 * Author: Zheng ShunQian<zhengsq@rock-chips.com> 6 */ 7 8#include <sound/soc.h> --- 182 unchanged lines hidden (view full) --- 191 {"HP Right Switch", "HP Right Out Switch", "HP Right Out"}, 192 193 {"HPL", NULL, "HP Left Switch"}, 194 {"HPR", NULL, "HP Right Switch"}, 195}; 196 197static int rk3036_codec_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 198{ |
199 struct snd_soc_codec *codec = dai->codec; | 199 struct snd_soc_component *component = dai->component; |
200 unsigned int reg01_val = 0, reg02_val = 0, reg03_val = 0; 201 | 200 unsigned int reg01_val = 0, reg02_val = 0, reg03_val = 0; 201 |
202 dev_dbg(codec->dev, "rk3036_codec dai set fmt : %08x\n", fmt); | 202 dev_dbg(component->dev, "rk3036_codec dai set fmt : %08x\n", fmt); |
203 204 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 205 case SND_SOC_DAIFMT_CBS_CFS: 206 reg01_val |= INNO_R01_PINDIR_IN_SLAVE | 207 INNO_R01_I2SMODE_SLAVE; 208 break; 209 case SND_SOC_DAIFMT_CBM_CFM: 210 reg01_val |= INNO_R01_PINDIR_OUT_MASTER | 211 INNO_R01_I2SMODE_MASTER; 212 break; 213 default: | 203 204 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 205 case SND_SOC_DAIFMT_CBS_CFS: 206 reg01_val |= INNO_R01_PINDIR_IN_SLAVE | 207 INNO_R01_I2SMODE_SLAVE; 208 break; 209 case SND_SOC_DAIFMT_CBM_CFM: 210 reg01_val |= INNO_R01_PINDIR_OUT_MASTER | 211 INNO_R01_I2SMODE_MASTER; 212 break; 213 default: |
214 dev_err(codec->dev, "invalid fmt\n"); | 214 dev_err(component->dev, "invalid fmt\n"); |
215 return -EINVAL; 216 } 217 218 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 219 case SND_SOC_DAIFMT_DSP_A: 220 reg02_val |= INNO_R02_DACM_PCM; 221 break; 222 case SND_SOC_DAIFMT_I2S: 223 reg02_val |= INNO_R02_DACM_I2S; 224 break; 225 case SND_SOC_DAIFMT_RIGHT_J: 226 reg02_val |= INNO_R02_DACM_RJM; 227 break; 228 case SND_SOC_DAIFMT_LEFT_J: 229 reg02_val |= INNO_R02_DACM_LJM; 230 break; 231 default: | 215 return -EINVAL; 216 } 217 218 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 219 case SND_SOC_DAIFMT_DSP_A: 220 reg02_val |= INNO_R02_DACM_PCM; 221 break; 222 case SND_SOC_DAIFMT_I2S: 223 reg02_val |= INNO_R02_DACM_I2S; 224 break; 225 case SND_SOC_DAIFMT_RIGHT_J: 226 reg02_val |= INNO_R02_DACM_RJM; 227 break; 228 case SND_SOC_DAIFMT_LEFT_J: 229 reg02_val |= INNO_R02_DACM_LJM; 230 break; 231 default: |
232 dev_err(codec->dev, "set dai format failed\n"); | 232 dev_err(component->dev, "set dai format failed\n"); |
233 return -EINVAL; 234 } 235 236 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 237 case SND_SOC_DAIFMT_NB_NF: 238 reg02_val |= INNO_R02_LRCP_NORMAL; 239 reg03_val |= INNO_R03_BCP_NORMAL; 240 break; --- 5 unchanged lines hidden (view full) --- 246 reg02_val |= INNO_R02_LRCP_REVERSAL; 247 reg03_val |= INNO_R03_BCP_NORMAL; 248 break; 249 case SND_SOC_DAIFMT_NB_IF: 250 reg02_val |= INNO_R02_LRCP_NORMAL; 251 reg03_val |= INNO_R03_BCP_REVERSAL; 252 break; 253 default: | 233 return -EINVAL; 234 } 235 236 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 237 case SND_SOC_DAIFMT_NB_NF: 238 reg02_val |= INNO_R02_LRCP_NORMAL; 239 reg03_val |= INNO_R03_BCP_NORMAL; 240 break; --- 5 unchanged lines hidden (view full) --- 246 reg02_val |= INNO_R02_LRCP_REVERSAL; 247 reg03_val |= INNO_R03_BCP_NORMAL; 248 break; 249 case SND_SOC_DAIFMT_NB_IF: 250 reg02_val |= INNO_R02_LRCP_NORMAL; 251 reg03_val |= INNO_R03_BCP_REVERSAL; 252 break; 253 default: |
254 dev_err(codec->dev, "set dai format failed\n"); | 254 dev_err(component->dev, "set dai format failed\n"); |
255 return -EINVAL; 256 } 257 | 255 return -EINVAL; 256 } 257 |
258 snd_soc_update_bits(codec, INNO_R01, INNO_R01_I2SMODE_MSK | | 258 snd_soc_component_update_bits(component, INNO_R01, INNO_R01_I2SMODE_MSK | |
259 INNO_R01_PINDIR_MSK, reg01_val); | 259 INNO_R01_PINDIR_MSK, reg01_val); |
260 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK | | 260 snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK | |
261 INNO_R02_DACM_MSK, reg02_val); | 261 INNO_R02_DACM_MSK, reg02_val); |
262 snd_soc_update_bits(codec, INNO_R03, INNO_R03_BCP_MSK, reg03_val); | 262 snd_soc_component_update_bits(component, INNO_R03, INNO_R03_BCP_MSK, reg03_val); |
263 264 return 0; 265} 266 267static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream, 268 struct snd_pcm_hw_params *hw_params, 269 struct snd_soc_dai *dai) 270{ | 263 264 return 0; 265} 266 267static int rk3036_codec_dai_hw_params(struct snd_pcm_substream *substream, 268 struct snd_pcm_hw_params *hw_params, 269 struct snd_soc_dai *dai) 270{ |
271 struct snd_soc_codec *codec = dai->codec; | 271 struct snd_soc_component *component = dai->component; |
272 unsigned int reg02_val = 0, reg03_val = 0; 273 274 switch (params_format(hw_params)) { 275 case SNDRV_PCM_FORMAT_S16_LE: 276 reg02_val |= INNO_R02_VWL_16BIT; 277 break; 278 case SNDRV_PCM_FORMAT_S20_3LE: 279 reg02_val |= INNO_R02_VWL_20BIT; --- 6 unchanged lines hidden (view full) --- 286 break; 287 default: 288 return -EINVAL; 289 } 290 291 reg02_val |= INNO_R02_LRCP_NORMAL; 292 reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK; 293 | 272 unsigned int reg02_val = 0, reg03_val = 0; 273 274 switch (params_format(hw_params)) { 275 case SNDRV_PCM_FORMAT_S16_LE: 276 reg02_val |= INNO_R02_VWL_16BIT; 277 break; 278 case SNDRV_PCM_FORMAT_S20_3LE: 279 reg02_val |= INNO_R02_VWL_20BIT; --- 6 unchanged lines hidden (view full) --- 286 break; 287 default: 288 return -EINVAL; 289 } 290 291 reg02_val |= INNO_R02_LRCP_NORMAL; 292 reg03_val |= INNO_R03_FWL_32BIT | INNO_R03_DACR_WORK; 293 |
294 snd_soc_update_bits(codec, INNO_R02, INNO_R02_LRCP_MSK | | 294 snd_soc_component_update_bits(component, INNO_R02, INNO_R02_LRCP_MSK | |
295 INNO_R02_VWL_MSK, reg02_val); | 295 INNO_R02_VWL_MSK, reg02_val); |
296 snd_soc_update_bits(codec, INNO_R03, INNO_R03_DACR_MSK | | 296 snd_soc_component_update_bits(component, INNO_R03, INNO_R03_DACR_MSK | |
297 INNO_R03_FWL_MSK, reg03_val); 298 return 0; 299} 300 301#define RK3036_CODEC_RATES (SNDRV_PCM_RATE_8000 | \ 302 SNDRV_PCM_RATE_16000 | \ 303 SNDRV_PCM_RATE_32000 | \ 304 SNDRV_PCM_RATE_44100 | \ --- 20 unchanged lines hidden (view full) --- 325 .rates = RK3036_CODEC_RATES, 326 .formats = RK3036_CODEC_FMTS, 327 }, 328 .ops = &rk3036_codec_dai_ops, 329 .symmetric_rates = 1, 330 }, 331}; 332 | 297 INNO_R03_FWL_MSK, reg03_val); 298 return 0; 299} 300 301#define RK3036_CODEC_RATES (SNDRV_PCM_RATE_8000 | \ 302 SNDRV_PCM_RATE_16000 | \ 303 SNDRV_PCM_RATE_32000 | \ 304 SNDRV_PCM_RATE_44100 | \ --- 20 unchanged lines hidden (view full) --- 325 .rates = RK3036_CODEC_RATES, 326 .formats = RK3036_CODEC_FMTS, 327 }, 328 .ops = &rk3036_codec_dai_ops, 329 .symmetric_rates = 1, 330 }, 331}; 332 |
333static void rk3036_codec_reset(struct snd_soc_codec *codec) | 333static void rk3036_codec_reset(struct snd_soc_component *component) |
334{ | 334{ |
335 snd_soc_write(codec, INNO_R00, | 335 snd_soc_component_write(component, INNO_R00, |
336 INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET); | 336 INNO_R00_CSR_RESET | INNO_R00_CDCR_RESET); |
337 snd_soc_write(codec, INNO_R00, | 337 snd_soc_component_write(component, INNO_R00, |
338 INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK); 339} 340 | 338 INNO_R00_CSR_WORK | INNO_R00_CDCR_WORK); 339} 340 |
341static int rk3036_codec_probe(struct snd_soc_codec *codec) | 341static int rk3036_codec_probe(struct snd_soc_component *component) |
342{ | 342{ |
343 rk3036_codec_reset(codec); | 343 rk3036_codec_reset(component); |
344 return 0; 345} 346 | 344 return 0; 345} 346 |
347static int rk3036_codec_remove(struct snd_soc_codec *codec) | 347static void rk3036_codec_remove(struct snd_soc_component *component) |
348{ | 348{ |
349 rk3036_codec_reset(codec); 350 return 0; | 349 rk3036_codec_reset(component); |
351} 352 | 350} 351 |
353static int rk3036_codec_set_bias_level(struct snd_soc_codec *codec, | 352static int rk3036_codec_set_bias_level(struct snd_soc_component *component, |
354 enum snd_soc_bias_level level) 355{ 356 switch (level) { 357 case SND_SOC_BIAS_STANDBY: 358 /* set a big current for capacitor charging. */ | 353 enum snd_soc_bias_level level) 354{ 355 switch (level) { 356 case SND_SOC_BIAS_STANDBY: 357 /* set a big current for capacitor charging. */ |
359 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR); | 358 snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR); |
360 /* start precharge */ | 359 /* start precharge */ |
361 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_PRECHARGE); | 360 snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_PRECHARGE); |
362 363 break; 364 365 case SND_SOC_BIAS_OFF: 366 /* set a big current for capacitor discharging. */ | 361 362 break; 363 364 case SND_SOC_BIAS_OFF: 365 /* set a big current for capacitor discharging. */ |
367 snd_soc_write(codec, INNO_R10, INNO_R10_MAX_CUR); | 366 snd_soc_component_write(component, INNO_R10, INNO_R10_MAX_CUR); |
368 /* start discharge. */ | 367 /* start discharge. */ |
369 snd_soc_write(codec, INNO_R06, INNO_R06_DAC_DISCHARGE); | 368 snd_soc_component_write(component, INNO_R06, INNO_R06_DAC_DISCHARGE); |
370 371 break; 372 default: 373 break; 374 } 375 376 return 0; 377} 378 | 369 370 break; 371 default: 372 break; 373 } 374 375 return 0; 376} 377 |
379static const struct snd_soc_codec_driver rk3036_codec_driver = { | 378static const struct snd_soc_component_driver rk3036_codec_driver = { |
380 .probe = rk3036_codec_probe, 381 .remove = rk3036_codec_remove, 382 .set_bias_level = rk3036_codec_set_bias_level, | 379 .probe = rk3036_codec_probe, 380 .remove = rk3036_codec_remove, 381 .set_bias_level = rk3036_codec_set_bias_level, |
383 .component_driver = { 384 .controls = rk3036_codec_dapm_controls, 385 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), 386 .dapm_routes = rk3036_codec_dapm_routes, 387 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), 388 .dapm_widgets = rk3036_codec_dapm_widgets, 389 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), 390 }, | 382 .controls = rk3036_codec_dapm_controls, 383 .num_controls = ARRAY_SIZE(rk3036_codec_dapm_controls), 384 .dapm_routes = rk3036_codec_dapm_routes, 385 .num_dapm_routes = ARRAY_SIZE(rk3036_codec_dapm_routes), 386 .dapm_widgets = rk3036_codec_dapm_widgets, 387 .num_dapm_widgets = ARRAY_SIZE(rk3036_codec_dapm_widgets), 388 .idle_bias_on = 1, 389 .use_pmdown_time = 1, 390 .endianness = 1, 391 .non_legacy_dai_naming = 1, |
391}; 392 393static const struct regmap_config rk3036_codec_regmap_config = { 394 .reg_bits = 32, 395 .reg_stride = 4, 396 .val_bits = 32, 397}; 398 --- 45 unchanged lines hidden (view full) --- 444 if (ret < 0) { 445 dev_err(&pdev->dev, "failed to enable clk\n"); 446 return ret; 447 } 448 449 priv->dev = &pdev->dev; 450 dev_set_drvdata(&pdev->dev, priv); 451 | 392}; 393 394static const struct regmap_config rk3036_codec_regmap_config = { 395 .reg_bits = 32, 396 .reg_stride = 4, 397 .val_bits = 32, 398}; 399 --- 45 unchanged lines hidden (view full) --- 445 if (ret < 0) { 446 dev_err(&pdev->dev, "failed to enable clk\n"); 447 return ret; 448 } 449 450 priv->dev = &pdev->dev; 451 dev_set_drvdata(&pdev->dev, priv); 452 |
452 ret = snd_soc_register_codec(&pdev->dev, &rk3036_codec_driver, | 453 ret = devm_snd_soc_register_component(&pdev->dev, &rk3036_codec_driver, |
453 rk3036_codec_dai_driver, 454 ARRAY_SIZE(rk3036_codec_dai_driver)); 455 if (ret) { 456 clk_disable_unprepare(priv->pclk); 457 dev_set_drvdata(&pdev->dev, NULL); 458 } 459 460 return ret; 461} 462 463static int rk3036_codec_platform_remove(struct platform_device *pdev) 464{ 465 struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev); 466 | 454 rk3036_codec_dai_driver, 455 ARRAY_SIZE(rk3036_codec_dai_driver)); 456 if (ret) { 457 clk_disable_unprepare(priv->pclk); 458 dev_set_drvdata(&pdev->dev, NULL); 459 } 460 461 return ret; 462} 463 464static int rk3036_codec_platform_remove(struct platform_device *pdev) 465{ 466 struct rk3036_codec_priv *priv = dev_get_drvdata(&pdev->dev); 467 |
467 snd_soc_unregister_codec(&pdev->dev); | |
468 clk_disable_unprepare(priv->pclk); 469 470 return 0; 471} 472 473static const struct of_device_id rk3036_codec_of_match[] = { 474 { .compatible = "rockchip,rk3036-codec", }, 475 {} --- 17 unchanged lines hidden --- | 468 clk_disable_unprepare(priv->pclk); 469 470 return 0; 471} 472 473static const struct of_device_id rk3036_codec_of_match[] = { 474 { .compatible = "rockchip,rk3036-codec", }, 475 {} --- 17 unchanged lines hidden --- |