aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5645.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5645.c')
-rw-r--r--sound/soc/codecs/rt5645.c292
1 files changed, 219 insertions, 73 deletions
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
index ef76940f9dcb..3e8d66661b7e 100644
--- a/sound/soc/codecs/rt5645.c
+++ b/sound/soc/codecs/rt5645.c
@@ -226,6 +226,163 @@ static const struct reg_default rt5645_reg[] = {
226 { 0xff, 0x6308 }, 226 { 0xff, 0x6308 },
227}; 227};
228 228
229static const struct reg_default rt5650_reg[] = {
230 { 0x00, 0x0000 },
231 { 0x01, 0xc8c8 },
232 { 0x02, 0xc8c8 },
233 { 0x03, 0xc8c8 },
234 { 0x0a, 0x0002 },
235 { 0x0b, 0x2827 },
236 { 0x0c, 0xe000 },
237 { 0x0d, 0x0000 },
238 { 0x0e, 0x0000 },
239 { 0x0f, 0x0808 },
240 { 0x14, 0x3333 },
241 { 0x16, 0x4b00 },
242 { 0x18, 0x018b },
243 { 0x19, 0xafaf },
244 { 0x1a, 0xafaf },
245 { 0x1b, 0x0001 },
246 { 0x1c, 0x2f2f },
247 { 0x1d, 0x2f2f },
248 { 0x1e, 0x0000 },
249 { 0x20, 0x0000 },
250 { 0x27, 0x7060 },
251 { 0x28, 0x7070 },
252 { 0x29, 0x8080 },
253 { 0x2a, 0x5656 },
254 { 0x2b, 0x5454 },
255 { 0x2c, 0xaaa0 },
256 { 0x2d, 0x0000 },
257 { 0x2f, 0x1002 },
258 { 0x31, 0x5000 },
259 { 0x32, 0x0000 },
260 { 0x33, 0x0000 },
261 { 0x34, 0x0000 },
262 { 0x35, 0x0000 },
263 { 0x3b, 0x0000 },
264 { 0x3c, 0x007f },
265 { 0x3d, 0x0000 },
266 { 0x3e, 0x007f },
267 { 0x3f, 0x0000 },
268 { 0x40, 0x001f },
269 { 0x41, 0x0000 },
270 { 0x42, 0x001f },
271 { 0x45, 0x6000 },
272 { 0x46, 0x003e },
273 { 0x47, 0x003e },
274 { 0x48, 0xf807 },
275 { 0x4a, 0x0004 },
276 { 0x4d, 0x0000 },
277 { 0x4e, 0x0000 },
278 { 0x4f, 0x01ff },
279 { 0x50, 0x0000 },
280 { 0x51, 0x0000 },
281 { 0x52, 0x01ff },
282 { 0x53, 0xf000 },
283 { 0x56, 0x0111 },
284 { 0x57, 0x0064 },
285 { 0x58, 0xef0e },
286 { 0x59, 0xf0f0 },
287 { 0x5a, 0xef0e },
288 { 0x5b, 0xf0f0 },
289 { 0x5c, 0xef0e },
290 { 0x5d, 0xf0f0 },
291 { 0x5e, 0xf000 },
292 { 0x5f, 0x0000 },
293 { 0x61, 0x0300 },
294 { 0x62, 0x0000 },
295 { 0x63, 0x00c2 },
296 { 0x64, 0x0000 },
297 { 0x65, 0x0000 },
298 { 0x66, 0x0000 },
299 { 0x6a, 0x0000 },
300 { 0x6c, 0x0aaa },
301 { 0x70, 0x8000 },
302 { 0x71, 0x8000 },
303 { 0x72, 0x8000 },
304 { 0x73, 0x7770 },
305 { 0x74, 0x3e00 },
306 { 0x75, 0x2409 },
307 { 0x76, 0x000a },
308 { 0x77, 0x0c00 },
309 { 0x78, 0x0000 },
310 { 0x79, 0x0123 },
311 { 0x7a, 0x0123 },
312 { 0x80, 0x0000 },
313 { 0x81, 0x0000 },
314 { 0x82, 0x0000 },
315 { 0x83, 0x0000 },
316 { 0x84, 0x0000 },
317 { 0x85, 0x0000 },
318 { 0x8a, 0x0000 },
319 { 0x8e, 0x0004 },
320 { 0x8f, 0x1100 },
321 { 0x90, 0x0646 },
322 { 0x91, 0x0c06 },
323 { 0x93, 0x0000 },
324 { 0x94, 0x0200 },
325 { 0x95, 0x0000 },
326 { 0x9a, 0x2184 },
327 { 0x9b, 0x010a },
328 { 0x9c, 0x0aea },
329 { 0x9d, 0x000c },
330 { 0x9e, 0x0400 },
331 { 0xa0, 0xa0a8 },
332 { 0xa1, 0x0059 },
333 { 0xa2, 0x0001 },
334 { 0xae, 0x6000 },
335 { 0xaf, 0x0000 },
336 { 0xb0, 0x6000 },
337 { 0xb1, 0x0000 },
338 { 0xb2, 0x0000 },
339 { 0xb3, 0x001f },
340 { 0xb4, 0x020c },
341 { 0xb5, 0x1f00 },
342 { 0xb6, 0x0000 },
343 { 0xbb, 0x0000 },
344 { 0xbc, 0x0000 },
345 { 0xbd, 0x0000 },
346 { 0xbe, 0x0000 },
347 { 0xbf, 0x3100 },
348 { 0xc0, 0x0000 },
349 { 0xc1, 0x0000 },
350 { 0xc2, 0x0000 },
351 { 0xc3, 0x2000 },
352 { 0xcd, 0x0000 },
353 { 0xce, 0x0000 },
354 { 0xcf, 0x1813 },
355 { 0xd0, 0x0690 },
356 { 0xd1, 0x1c17 },
357 { 0xd3, 0xb320 },
358 { 0xd4, 0x0000 },
359 { 0xd6, 0x0400 },
360 { 0xd9, 0x0809 },
361 { 0xda, 0x0000 },
362 { 0xdb, 0x0003 },
363 { 0xdc, 0x0049 },
364 { 0xdd, 0x001b },
365 { 0xdf, 0x0008 },
366 { 0xe0, 0x4000 },
367 { 0xe6, 0x8000 },
368 { 0xe7, 0x0200 },
369 { 0xec, 0xb300 },
370 { 0xed, 0x0000 },
371 { 0xf0, 0x001f },
372 { 0xf1, 0x020c },
373 { 0xf2, 0x1f00 },
374 { 0xf3, 0x0000 },
375 { 0xf4, 0x4000 },
376 { 0xf8, 0x0000 },
377 { 0xf9, 0x0000 },
378 { 0xfa, 0x2060 },
379 { 0xfb, 0x4040 },
380 { 0xfc, 0x0000 },
381 { 0xfd, 0x0002 },
382 { 0xfe, 0x10ec },
383 { 0xff, 0x6308 },
384};
385
229struct rt5645_eq_param_s { 386struct rt5645_eq_param_s {
230 unsigned short reg; 387 unsigned short reg;
231 unsigned short val; 388 unsigned short val;
@@ -572,14 +729,12 @@ static int rt5645_spk_put_volsw(struct snd_kcontrol *kcontrol,
572 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); 729 struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component);
573 int ret; 730 int ret;
574 731
575 cancel_delayed_work_sync(&rt5645->rcclock_work);
576
577 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS, 732 regmap_update_bits(rt5645->regmap, RT5645_MICBIAS,
578 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU); 733 RT5645_PWR_CLK25M_MASK, RT5645_PWR_CLK25M_PU);
579 734
580 ret = snd_soc_put_volsw(kcontrol, ucontrol); 735 ret = snd_soc_put_volsw(kcontrol, ucontrol);
581 736
582 queue_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work, 737 mod_delayed_work(system_power_efficient_wq, &rt5645->rcclock_work,
583 msecs_to_jiffies(200)); 738 msecs_to_jiffies(200));
584 739
585 return ret; 740 return ret;
@@ -3318,6 +3473,31 @@ static const struct regmap_config rt5645_regmap = {
3318 .num_ranges = ARRAY_SIZE(rt5645_ranges), 3473 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3319}; 3474};
3320 3475
3476static const struct regmap_config rt5650_regmap = {
3477 .reg_bits = 8,
3478 .val_bits = 16,
3479 .use_single_rw = true,
3480 .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) *
3481 RT5645_PR_SPACING),
3482 .volatile_reg = rt5645_volatile_register,
3483 .readable_reg = rt5645_readable_register,
3484
3485 .cache_type = REGCACHE_RBTREE,
3486 .reg_defaults = rt5650_reg,
3487 .num_reg_defaults = ARRAY_SIZE(rt5650_reg),
3488 .ranges = rt5645_ranges,
3489 .num_ranges = ARRAY_SIZE(rt5645_ranges),
3490};
3491
3492static const struct regmap_config temp_regmap = {
3493 .name="nocache",
3494 .reg_bits = 8,
3495 .val_bits = 16,
3496 .use_single_rw = true,
3497 .max_register = RT5645_VENDOR_ID2 + 1,
3498 .cache_type = REGCACHE_NONE,
3499};
3500
3321static const struct i2c_device_id rt5645_i2c_id[] = { 3501static const struct i2c_device_id rt5645_i2c_id[] = {
3322 { "rt5645", 0 }, 3502 { "rt5645", 0 },
3323 { "rt5650", 0 }, 3503 { "rt5650", 0 },
@@ -3334,69 +3514,23 @@ static struct acpi_device_id rt5645_acpi_match[] = {
3334MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); 3514MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
3335#endif 3515#endif
3336 3516
3337static struct rt5645_platform_data *rt5645_pdata; 3517static struct rt5645_platform_data general_platform_data = {
3338
3339static struct rt5645_platform_data strago_platform_data = {
3340 .dmic1_data_pin = RT5645_DMIC1_DISABLE, 3518 .dmic1_data_pin = RT5645_DMIC1_DISABLE,
3341 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, 3519 .dmic2_data_pin = RT5645_DMIC_DATA_IN2P,
3342 .jd_mode = 3, 3520 .jd_mode = 3,
3343}; 3521};
3344 3522
3345static int strago_quirk_cb(const struct dmi_system_id *id)
3346{
3347 rt5645_pdata = &strago_platform_data;
3348
3349 return 1;
3350}
3351
3352static const struct dmi_system_id dmi_platform_intel_braswell[] = { 3523static const struct dmi_system_id dmi_platform_intel_braswell[] = {
3353 { 3524 {
3354 .ident = "Intel Strago", 3525 .ident = "Intel Strago",
3355 .callback = strago_quirk_cb,
3356 .matches = { 3526 .matches = {
3357 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), 3527 DMI_MATCH(DMI_PRODUCT_NAME, "Strago"),
3358 }, 3528 },
3359 }, 3529 },
3360 { 3530 {
3361 .ident = "Google Celes", 3531 .ident = "Google Chrome",
3362 .callback = strago_quirk_cb,
3363 .matches = {
3364 DMI_MATCH(DMI_PRODUCT_NAME, "Celes"),
3365 },
3366 },
3367 {
3368 .ident = "Google Ultima",
3369 .callback = strago_quirk_cb,
3370 .matches = {
3371 DMI_MATCH(DMI_PRODUCT_NAME, "Ultima"),
3372 },
3373 },
3374 {
3375 .ident = "Google Reks",
3376 .callback = strago_quirk_cb,
3377 .matches = {
3378 DMI_MATCH(DMI_PRODUCT_NAME, "Reks"),
3379 },
3380 },
3381 {
3382 .ident = "Google Edgar",
3383 .callback = strago_quirk_cb,
3384 .matches = {
3385 DMI_MATCH(DMI_PRODUCT_NAME, "Edgar"),
3386 },
3387 },
3388 {
3389 .ident = "Google Wizpig",
3390 .callback = strago_quirk_cb,
3391 .matches = {
3392 DMI_MATCH(DMI_PRODUCT_NAME, "Wizpig"),
3393 },
3394 },
3395 {
3396 .ident = "Google Terra",
3397 .callback = strago_quirk_cb,
3398 .matches = { 3532 .matches = {
3399 DMI_MATCH(DMI_PRODUCT_NAME, "Terra"), 3533 DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
3400 }, 3534 },
3401 }, 3535 },
3402 { } 3536 { }
@@ -3409,17 +3543,9 @@ static struct rt5645_platform_data buddy_platform_data = {
3409 .jd_invert = true, 3543 .jd_invert = true,
3410}; 3544};
3411 3545
3412static int buddy_quirk_cb(const struct dmi_system_id *id)
3413{
3414 rt5645_pdata = &buddy_platform_data;
3415
3416 return 1;
3417}
3418
3419static struct dmi_system_id dmi_platform_intel_broadwell[] = { 3546static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3420 { 3547 {
3421 .ident = "Chrome Buddy", 3548 .ident = "Chrome Buddy",
3422 .callback = buddy_quirk_cb,
3423 .matches = { 3549 .matches = {
3424 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), 3550 DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"),
3425 }, 3551 },
@@ -3427,6 +3553,16 @@ static struct dmi_system_id dmi_platform_intel_broadwell[] = {
3427 { } 3553 { }
3428}; 3554};
3429 3555
3556static bool rt5645_check_dp(struct device *dev)
3557{
3558 if (device_property_present(dev, "realtek,in2-differential") ||
3559 device_property_present(dev, "realtek,dmic1-data-pin") ||
3560 device_property_present(dev, "realtek,dmic2-data-pin") ||
3561 device_property_present(dev, "realtek,jd-mode"))
3562 return true;
3563
3564 return false;
3565}
3430 3566
3431static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev) 3567static int rt5645_parse_dt(struct rt5645_priv *rt5645, struct device *dev)
3432{ 3568{
@@ -3449,6 +3585,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3449 struct rt5645_priv *rt5645; 3585 struct rt5645_priv *rt5645;
3450 int ret, i; 3586 int ret, i;
3451 unsigned int val; 3587 unsigned int val;
3588 struct regmap *regmap;
3452 3589
3453 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), 3590 rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv),
3454 GFP_KERNEL); 3591 GFP_KERNEL);
@@ -3460,11 +3597,12 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3460 3597
3461 if (pdata) 3598 if (pdata)
3462 rt5645->pdata = *pdata; 3599 rt5645->pdata = *pdata;
3463 else if (dmi_check_system(dmi_platform_intel_braswell) || 3600 else if (dmi_check_system(dmi_platform_intel_broadwell))
3464 dmi_check_system(dmi_platform_intel_broadwell)) 3601 rt5645->pdata = buddy_platform_data;
3465 rt5645->pdata = *rt5645_pdata; 3602 else if (rt5645_check_dp(&i2c->dev))
3466 else
3467 rt5645_parse_dt(rt5645, &i2c->dev); 3603 rt5645_parse_dt(rt5645, &i2c->dev);
3604 else if (dmi_check_system(dmi_platform_intel_braswell))
3605 rt5645->pdata = general_platform_data;
3468 3606
3469 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect", 3607 rt5645->gpiod_hp_det = devm_gpiod_get_optional(&i2c->dev, "hp-detect",
3470 GPIOD_IN); 3608 GPIOD_IN);
@@ -3474,14 +3612,6 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3474 return PTR_ERR(rt5645->gpiod_hp_det); 3612 return PTR_ERR(rt5645->gpiod_hp_det);
3475 } 3613 }
3476 3614
3477 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3478 if (IS_ERR(rt5645->regmap)) {
3479 ret = PTR_ERR(rt5645->regmap);
3480 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3481 ret);
3482 return ret;
3483 }
3484
3485 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++) 3615 for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
3486 rt5645->supplies[i].supply = rt5645_supply_names[i]; 3616 rt5645->supplies[i].supply = rt5645_supply_names[i];
3487 3617
@@ -3500,13 +3630,22 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3500 return ret; 3630 return ret;
3501 } 3631 }
3502 3632
3503 regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); 3633 regmap = devm_regmap_init_i2c(i2c, &temp_regmap);
3634 if (IS_ERR(regmap)) {
3635 ret = PTR_ERR(regmap);
3636 dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n",
3637 ret);
3638 return ret;
3639 }
3640 regmap_read(regmap, RT5645_VENDOR_ID2, &val);
3504 3641
3505 switch (val) { 3642 switch (val) {
3506 case RT5645_DEVICE_ID: 3643 case RT5645_DEVICE_ID:
3644 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap);
3507 rt5645->codec_type = CODEC_TYPE_RT5645; 3645 rt5645->codec_type = CODEC_TYPE_RT5645;
3508 break; 3646 break;
3509 case RT5650_DEVICE_ID: 3647 case RT5650_DEVICE_ID:
3648 rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5650_regmap);
3510 rt5645->codec_type = CODEC_TYPE_RT5650; 3649 rt5645->codec_type = CODEC_TYPE_RT5650;
3511 break; 3650 break;
3512 default: 3651 default:
@@ -3517,6 +3656,13 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
3517 goto err_enable; 3656 goto err_enable;
3518 } 3657 }
3519 3658
3659 if (IS_ERR(rt5645->regmap)) {
3660 ret = PTR_ERR(rt5645->regmap);
3661 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
3662 ret);
3663 return ret;
3664 }
3665
3520 regmap_write(rt5645->regmap, RT5645_RESET, 0); 3666 regmap_write(rt5645->regmap, RT5645_RESET, 0);
3521 3667
3522 ret = regmap_register_patch(rt5645->regmap, init_list, 3668 ret = regmap_register_patch(rt5645->regmap, init_list,