1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // CS35l41 ALSA HDA audio driver 4 // 5 // Copyright 2021 Cirrus Logic, Inc. 6 // 7 // Author: Lucas Tanure <tanureal@opensource.cirrus.com> 8 9 #include <linux/acpi.h> 10 #include <linux/module.h> 11 #include <sound/hda_codec.h> 12 #include "hda_local.h" 13 #include "hda_auto_parser.h" 14 #include "hda_jack.h" 15 #include "hda_generic.h" 16 #include "hda_component.h" 17 #include "cs35l41_hda.h" 18 19 static const struct reg_sequence cs35l41_hda_config[] = { 20 { CS35L41_PLL_CLK_CTRL, 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1 21 { CS35L41_GLOBAL_CLK_CTRL, 0x00000003 }, // GLOBAL_FS = 48 kHz 22 { CS35L41_SP_ENABLES, 0x00010000 }, // ASP_RX1_EN = 1 23 { CS35L41_SP_RATE_CTRL, 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz 24 { CS35L41_SP_FORMAT, 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer 25 { CS35L41_DAC_PCM1_SRC, 0x00000008 }, // DACPCM1_SRC = ASPRX1 26 { CS35L41_AMP_DIG_VOL_CTRL, 0x00000000 }, // AMP_VOL_PCM 0.0 dB 27 { CS35L41_AMP_GAIN_CTRL, 0x00000084 }, // AMP_GAIN_PCM 4.5 dB 28 }; 29 30 static const struct reg_sequence cs35l41_hda_mute[] = { 31 { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, // AMP_GAIN_PCM 0.5 dB 32 { CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute 33 }; 34 35 // only on amps where GPIO1 is used to control ext. VSPK switch 36 static const struct reg_sequence cs35l41_start_ext_vspk[] = { 37 { 0x00000040, 0x00000055 }, 38 { 0x00000040, 0x000000AA }, 39 { 0x00007438, 0x00585941 }, 40 { 0x00007414, 0x08C82222 }, 41 { 0x0000742C, 0x00000009 }, 42 { 0x00011008, 0x00008001 }, 43 { 0x0000742C, 0x0000000F }, 44 { 0x0000742C, 0x00000079 }, 45 { 0x00007438, 0x00585941 }, 46 { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1 47 { 0x0000742C, 0x000000F9 }, 48 { 0x00007438, 0x00580941 }, 49 { 0x00000040, 0x000000CC }, 50 { 0x00000040, 0x00000033 }, 51 }; 52 53 //only on amps where GPIO1 is used to control ext. VSPK switch 54 static const struct reg_sequence cs35l41_stop_ext_vspk[] = { 55 { 0x00000040, 0x00000055 }, 56 { 0x00000040, 0x000000AA }, 57 { 0x00007438, 0x00585941 }, 58 { 0x00002014, 0x00000000, 3000}, // set GLOBAL_EN = 0 59 { 0x0000742C, 0x00000009 }, 60 { 0x00007438, 0x00580941 }, 61 { 0x00011008, 0x00000001 }, 62 { 0x0000393C, 0x000000C0, 6000}, 63 { 0x0000393C, 0x00000000 }, 64 { 0x00007414, 0x00C82222 }, 65 { 0x0000742C, 0x00000000 }, 66 { 0x00000040, 0x000000CC }, 67 { 0x00000040, 0x00000033 }, 68 }; 69 70 static const struct reg_sequence cs35l41_safe_to_active[] = { 71 { 0x00000040, 0x00000055 }, 72 { 0x00000040, 0x000000AA }, 73 { 0x0000742C, 0x0000000F }, 74 { 0x0000742C, 0x00000079 }, 75 { 0x00007438, 0x00585941 }, 76 { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, // GLOBAL_EN = 1 77 { 0x0000742C, 0x000000F9 }, 78 { 0x00007438, 0x00580941 }, 79 { 0x00000040, 0x000000CC }, 80 { 0x00000040, 0x00000033 }, 81 }; 82 83 static const struct reg_sequence cs35l41_active_to_safe[] = { 84 { 0x00000040, 0x00000055 }, 85 { 0x00000040, 0x000000AA }, 86 { 0x00007438, 0x00585941 }, 87 { CS35L41_PWR_CTRL1, 0x00000000 }, 88 { 0x0000742C, 0x00000009, 2000 }, 89 { 0x00007438, 0x00580941 }, 90 { 0x00000040, 0x000000CC }, 91 { 0x00000040, 0x00000033 }, 92 }; 93 94 static const struct reg_sequence cs35l41_reset_to_safe[] = { 95 { 0x00000040, 0x00000055 }, 96 { 0x00000040, 0x000000AA }, 97 { 0x00007438, 0x00585941 }, 98 { 0x00007414, 0x08C82222 }, 99 { 0x0000742C, 0x00000009 }, 100 { 0x00000040, 0x000000CC }, 101 { 0x00000040, 0x00000033 }, 102 }; 103 104 static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable) 105 { 106 int ret; 107 108 switch (cs35l41->hw_cfg.bst_type) { 109 case CS35L41_INT_BOOST: 110 ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1, 111 CS35L41_GLOBAL_EN_MASK, 112 enable << CS35L41_GLOBAL_EN_SHIFT); 113 usleep_range(3000, 3100); 114 break; 115 case CS35L41_EXT_BOOST: 116 if (enable) 117 ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_start_ext_vspk, 118 ARRAY_SIZE(cs35l41_start_ext_vspk)); 119 else 120 ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_stop_ext_vspk, 121 ARRAY_SIZE(cs35l41_stop_ext_vspk)); 122 break; 123 case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: 124 if (enable) 125 ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active, 126 ARRAY_SIZE(cs35l41_safe_to_active)); 127 else 128 ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_active_to_safe, 129 ARRAY_SIZE(cs35l41_active_to_safe)); 130 break; 131 default: 132 ret = -EINVAL; 133 break; 134 } 135 136 return ret; 137 }; 138 139 static void cs35l41_hda_playback_hook(struct device *dev, int action) 140 { 141 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 142 struct regmap *reg = cs35l41->regmap; 143 int ret = 0; 144 145 switch (action) { 146 case HDA_GEN_PCM_ACT_OPEN: 147 regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); 148 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, 149 CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); 150 break; 151 case HDA_GEN_PCM_ACT_PREPARE: 152 ret = cs35l41_hda_global_enable(cs35l41, 1); 153 break; 154 case HDA_GEN_PCM_ACT_CLEANUP: 155 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); 156 ret = cs35l41_hda_global_enable(cs35l41, 0); 157 break; 158 case HDA_GEN_PCM_ACT_CLOSE: 159 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, 160 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); 161 break; 162 default: 163 dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); 164 break; 165 } 166 167 if (ret) 168 dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); 169 } 170 171 static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot, 172 unsigned int rx_num, unsigned int *rx_slot) 173 { 174 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 175 176 return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num, 177 rx_slot); 178 } 179 180 static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) 181 { 182 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 183 struct hda_component *comps = master_data; 184 185 if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) 186 return -EINVAL; 187 188 comps = &comps[cs35l41->index]; 189 if (comps->dev) 190 return -EBUSY; 191 192 comps->dev = dev; 193 strscpy(comps->name, dev_name(dev), sizeof(comps->name)); 194 comps->playback_hook = cs35l41_hda_playback_hook; 195 comps->set_channel_map = cs35l41_hda_channel_map; 196 197 return 0; 198 } 199 200 static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) 201 { 202 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 203 struct hda_component *comps = master_data; 204 205 if (comps[cs35l41->index].dev == dev) 206 memset(&comps[cs35l41->index], 0, sizeof(*comps)); 207 } 208 209 static const struct component_ops cs35l41_hda_comp_ops = { 210 .bind = cs35l41_hda_bind, 211 .unbind = cs35l41_hda_unbind, 212 }; 213 214 static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) 215 { 216 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; 217 int ret; 218 219 if (!cs35l41->hw_cfg.valid) 220 return -EINVAL; 221 222 switch (hw_cfg->bst_type) { 223 case CS35L41_INT_BOOST: 224 ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, 225 hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk); 226 if (ret) 227 return ret; 228 break; 229 case CS35L41_EXT_BOOST: 230 case CS35L41_EXT_BOOST_NO_VSPK_SWITCH: 231 regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe, 232 ARRAY_SIZE(cs35l41_reset_to_safe)); 233 ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK, 234 CS35L41_BST_DIS_FET_OFF << CS35L41_BST_EN_SHIFT); 235 if (ret) 236 return ret; 237 break; 238 default: 239 dev_err(cs35l41->dev, "Boost type %d not supported\n", hw_cfg->bst_type); 240 return -EINVAL; 241 } 242 243 if (hw_cfg->gpio1.valid) { 244 switch (hw_cfg->gpio1.func) { 245 case CS35L41_NOT_USED: 246 break; 247 case CS35l41_VSPK_SWITCH: 248 hw_cfg->gpio1.func = CS35L41_GPIO1_GPIO; 249 hw_cfg->gpio1.out_en = true; 250 break; 251 case CS35l41_SYNC: 252 hw_cfg->gpio1.func = CS35L41_GPIO1_MDSYNC; 253 break; 254 default: 255 dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", 256 hw_cfg->gpio1.func); 257 return -EINVAL; 258 } 259 } 260 261 if (hw_cfg->gpio2.valid) { 262 switch (hw_cfg->gpio2.func) { 263 case CS35L41_NOT_USED: 264 break; 265 case CS35L41_INTERRUPT: 266 break; 267 default: 268 dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); 269 return -EINVAL; 270 } 271 } 272 273 cs35l41_gpio_config(cs35l41->regmap, hw_cfg); 274 275 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); 276 } 277 278 static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) 279 { 280 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; 281 u32 values[HDA_MAX_COMPONENTS]; 282 struct acpi_device *adev; 283 struct device *physdev; 284 char *property; 285 size_t nval; 286 int i, ret; 287 288 adev = acpi_dev_get_first_match_dev(hid, NULL, -1); 289 if (!adev) { 290 dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); 291 return -ENODEV; 292 } 293 294 physdev = get_device(acpi_get_first_physical_node(adev)); 295 acpi_dev_put(adev); 296 297 property = "cirrus,dev-index"; 298 ret = device_property_count_u32(physdev, property); 299 if (ret <= 0) 300 goto no_acpi_dsd; 301 302 if (ret > ARRAY_SIZE(values)) { 303 ret = -EINVAL; 304 goto err; 305 } 306 nval = ret; 307 308 ret = device_property_read_u32_array(physdev, property, values, nval); 309 if (ret) 310 goto err; 311 312 cs35l41->index = -1; 313 for (i = 0; i < nval; i++) { 314 if (values[i] == id) { 315 cs35l41->index = i; 316 break; 317 } 318 } 319 if (cs35l41->index == -1) { 320 dev_err(cs35l41->dev, "No index found in %s\n", property); 321 ret = -ENODEV; 322 goto err; 323 } 324 325 /* To use the same release code for all laptop variants we can't use devm_ version of 326 * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node 327 */ 328 cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, 329 GPIOD_OUT_LOW, "cs35l41-reset"); 330 331 property = "cirrus,speaker-position"; 332 ret = device_property_read_u32_array(physdev, property, values, nval); 333 if (ret) 334 goto err; 335 hw_cfg->spk_pos = values[cs35l41->index]; 336 337 property = "cirrus,gpio1-func"; 338 ret = device_property_read_u32_array(physdev, property, values, nval); 339 if (ret) 340 goto err; 341 hw_cfg->gpio1.func = values[cs35l41->index]; 342 hw_cfg->gpio1.valid = true; 343 344 property = "cirrus,gpio2-func"; 345 ret = device_property_read_u32_array(physdev, property, values, nval); 346 if (ret) 347 goto err; 348 hw_cfg->gpio2.func = values[cs35l41->index]; 349 hw_cfg->gpio2.valid = true; 350 351 property = "cirrus,boost-peak-milliamp"; 352 ret = device_property_read_u32_array(physdev, property, values, nval); 353 if (ret == 0) 354 hw_cfg->bst_ipk = values[cs35l41->index]; 355 else 356 hw_cfg->bst_ipk = -1; 357 358 property = "cirrus,boost-ind-nanohenry"; 359 ret = device_property_read_u32_array(physdev, property, values, nval); 360 if (ret == 0) 361 hw_cfg->bst_ind = values[cs35l41->index]; 362 else 363 hw_cfg->bst_ind = -1; 364 365 property = "cirrus,boost-cap-microfarad"; 366 ret = device_property_read_u32_array(physdev, property, values, nval); 367 if (ret == 0) 368 hw_cfg->bst_cap = values[cs35l41->index]; 369 else 370 hw_cfg->bst_cap = -1; 371 372 if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) 373 hw_cfg->bst_type = CS35L41_INT_BOOST; 374 else 375 hw_cfg->bst_type = CS35L41_EXT_BOOST; 376 377 hw_cfg->valid = true; 378 put_device(physdev); 379 380 return 0; 381 382 err: 383 put_device(physdev); 384 dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); 385 386 return ret; 387 388 no_acpi_dsd: 389 /* 390 * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. 391 * And devices created by i2c-multi-instantiate don't have their device struct pointing to 392 * the correct fwnode, so acpi_dev must be used here. 393 * And devm functions expect that the device requesting the resource has the correct 394 * fwnode. 395 */ 396 if (strncmp(hid, "CLSA0100", 8) != 0) 397 return -EINVAL; 398 399 /* check I2C address to assign the index */ 400 cs35l41->index = id == 0x40 ? 0 : 1; 401 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); 402 cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; 403 cs35l41->hw_cfg.valid = true; 404 put_device(physdev); 405 406 return 0; 407 } 408 409 int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, 410 struct regmap *regmap) 411 { 412 unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; 413 struct cs35l41_hda *cs35l41; 414 int ret; 415 416 if (IS_ERR(regmap)) 417 return PTR_ERR(regmap); 418 419 cs35l41 = devm_kzalloc(dev, sizeof(*cs35l41), GFP_KERNEL); 420 if (!cs35l41) 421 return -ENOMEM; 422 423 cs35l41->dev = dev; 424 cs35l41->irq = irq; 425 cs35l41->regmap = regmap; 426 dev_set_drvdata(dev, cs35l41); 427 428 ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); 429 if (ret) { 430 dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret); 431 return ret; 432 } 433 434 if (IS_ERR(cs35l41->reset_gpio)) { 435 ret = PTR_ERR(cs35l41->reset_gpio); 436 cs35l41->reset_gpio = NULL; 437 if (ret == -EBUSY) { 438 dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); 439 } else { 440 dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO: %d\n", ret); 441 goto err; 442 } 443 } 444 if (cs35l41->reset_gpio) { 445 usleep_range(2000, 2100); 446 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); 447 } 448 449 usleep_range(2000, 2100); 450 451 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, 452 int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000); 453 if (ret) { 454 dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret); 455 goto err; 456 } 457 458 ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); 459 if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) { 460 dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n", 461 int_sts & CS35L41_OTP_BOOT_ERR, ret); 462 ret = -EIO; 463 goto err; 464 } 465 466 ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); 467 if (ret) { 468 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); 469 goto err; 470 } 471 472 ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); 473 if (ret) { 474 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); 475 goto err; 476 } 477 478 mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; 479 480 chipid = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; 481 if (regid != chipid) { 482 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", regid, chipid); 483 ret = -ENODEV; 484 goto err; 485 } 486 487 ret = cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); 488 if (ret) 489 goto err; 490 491 ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); 492 if (ret) 493 goto err; 494 495 ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); 496 if (ret) { 497 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); 498 goto err; 499 } 500 501 ret = cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); 502 if (ret) 503 goto err; 504 505 ret = cs35l41_hda_apply_properties(cs35l41); 506 if (ret) 507 goto err; 508 509 ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); 510 if (ret) { 511 dev_err(cs35l41->dev, "Register component failed: %d\n", ret); 512 goto err; 513 } 514 515 dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); 516 517 return 0; 518 519 err: 520 if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) 521 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 522 gpiod_put(cs35l41->reset_gpio); 523 524 return ret; 525 } 526 EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, SND_HDA_SCODEC_CS35L41); 527 528 void cs35l41_hda_remove(struct device *dev) 529 { 530 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 531 532 component_del(cs35l41->dev, &cs35l41_hda_comp_ops); 533 534 if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH) 535 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 536 gpiod_put(cs35l41->reset_gpio); 537 } 538 EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); 539 540 MODULE_DESCRIPTION("CS35L41 HDA Driver"); 541 MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); 542 MODULE_LICENSE("GPL"); 543