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 static void cs35l41_hda_playback_hook(struct device *dev, int action) 36 { 37 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 38 struct regmap *reg = cs35l41->regmap; 39 int ret = 0; 40 41 switch (action) { 42 case HDA_GEN_PCM_ACT_OPEN: 43 regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config)); 44 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, 45 CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT); 46 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) 47 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001); 48 break; 49 case HDA_GEN_PCM_ACT_PREPARE: 50 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 1); 51 break; 52 case HDA_GEN_PCM_ACT_CLEANUP: 53 regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute)); 54 ret = cs35l41_global_enable(reg, cs35l41->hw_cfg.bst_type, 0); 55 break; 56 case HDA_GEN_PCM_ACT_CLOSE: 57 ret = regmap_update_bits(reg, CS35L41_PWR_CTRL2, 58 CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT); 59 if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) 60 regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001); 61 break; 62 default: 63 dev_warn(cs35l41->dev, "Playback action not supported: %d\n", action); 64 break; 65 } 66 67 if (ret) 68 dev_err(cs35l41->dev, "Regmap access fail: %d\n", ret); 69 } 70 71 static int cs35l41_hda_channel_map(struct device *dev, unsigned int tx_num, unsigned int *tx_slot, 72 unsigned int rx_num, unsigned int *rx_slot) 73 { 74 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 75 76 return cs35l41_set_channels(cs35l41->dev, cs35l41->regmap, tx_num, tx_slot, rx_num, 77 rx_slot); 78 } 79 80 static int cs35l41_hda_bind(struct device *dev, struct device *master, void *master_data) 81 { 82 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 83 struct hda_component *comps = master_data; 84 85 if (!comps || cs35l41->index < 0 || cs35l41->index >= HDA_MAX_COMPONENTS) 86 return -EINVAL; 87 88 comps = &comps[cs35l41->index]; 89 if (comps->dev) 90 return -EBUSY; 91 92 comps->dev = dev; 93 strscpy(comps->name, dev_name(dev), sizeof(comps->name)); 94 comps->playback_hook = cs35l41_hda_playback_hook; 95 comps->set_channel_map = cs35l41_hda_channel_map; 96 97 return 0; 98 } 99 100 static void cs35l41_hda_unbind(struct device *dev, struct device *master, void *master_data) 101 { 102 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 103 struct hda_component *comps = master_data; 104 105 if (comps[cs35l41->index].dev == dev) 106 memset(&comps[cs35l41->index], 0, sizeof(*comps)); 107 } 108 109 static const struct component_ops cs35l41_hda_comp_ops = { 110 .bind = cs35l41_hda_bind, 111 .unbind = cs35l41_hda_unbind, 112 }; 113 114 static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41) 115 { 116 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; 117 int ret; 118 119 if (!cs35l41->hw_cfg.valid) 120 return -EINVAL; 121 122 ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg); 123 if (ret) 124 return ret; 125 126 if (hw_cfg->gpio1.valid) { 127 switch (hw_cfg->gpio1.func) { 128 case CS35L41_NOT_USED: 129 break; 130 case CS35l41_VSPK_SWITCH: 131 hw_cfg->gpio1.func = CS35L41_GPIO1_GPIO; 132 hw_cfg->gpio1.out_en = true; 133 break; 134 case CS35l41_SYNC: 135 hw_cfg->gpio1.func = CS35L41_GPIO1_MDSYNC; 136 break; 137 default: 138 dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", 139 hw_cfg->gpio1.func); 140 return -EINVAL; 141 } 142 } 143 144 if (hw_cfg->gpio2.valid) { 145 switch (hw_cfg->gpio2.func) { 146 case CS35L41_NOT_USED: 147 break; 148 case CS35L41_INTERRUPT: 149 break; 150 default: 151 dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func); 152 return -EINVAL; 153 } 154 } 155 156 cs35l41_gpio_config(cs35l41->regmap, hw_cfg); 157 158 return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos); 159 } 160 161 static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id) 162 { 163 struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg; 164 u32 values[HDA_MAX_COMPONENTS]; 165 struct acpi_device *adev; 166 struct device *physdev; 167 char *property; 168 size_t nval; 169 int i, ret; 170 171 adev = acpi_dev_get_first_match_dev(hid, NULL, -1); 172 if (!adev) { 173 dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); 174 return -ENODEV; 175 } 176 177 physdev = get_device(acpi_get_first_physical_node(adev)); 178 acpi_dev_put(adev); 179 180 property = "cirrus,dev-index"; 181 ret = device_property_count_u32(physdev, property); 182 if (ret <= 0) 183 goto no_acpi_dsd; 184 185 if (ret > ARRAY_SIZE(values)) { 186 ret = -EINVAL; 187 goto err; 188 } 189 nval = ret; 190 191 ret = device_property_read_u32_array(physdev, property, values, nval); 192 if (ret) 193 goto err; 194 195 cs35l41->index = -1; 196 for (i = 0; i < nval; i++) { 197 if (values[i] == id) { 198 cs35l41->index = i; 199 break; 200 } 201 } 202 if (cs35l41->index == -1) { 203 dev_err(cs35l41->dev, "No index found in %s\n", property); 204 ret = -ENODEV; 205 goto err; 206 } 207 208 /* To use the same release code for all laptop variants we can't use devm_ version of 209 * gpiod_get here, as CLSA010* don't have a fully functional bios with an _DSD node 210 */ 211 cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index, 212 GPIOD_OUT_LOW, "cs35l41-reset"); 213 214 property = "cirrus,speaker-position"; 215 ret = device_property_read_u32_array(physdev, property, values, nval); 216 if (ret) 217 goto err; 218 hw_cfg->spk_pos = values[cs35l41->index]; 219 220 property = "cirrus,gpio1-func"; 221 ret = device_property_read_u32_array(physdev, property, values, nval); 222 if (ret) 223 goto err; 224 hw_cfg->gpio1.func = values[cs35l41->index]; 225 hw_cfg->gpio1.valid = true; 226 227 property = "cirrus,gpio2-func"; 228 ret = device_property_read_u32_array(physdev, property, values, nval); 229 if (ret) 230 goto err; 231 hw_cfg->gpio2.func = values[cs35l41->index]; 232 hw_cfg->gpio2.valid = true; 233 234 property = "cirrus,boost-peak-milliamp"; 235 ret = device_property_read_u32_array(physdev, property, values, nval); 236 if (ret == 0) 237 hw_cfg->bst_ipk = values[cs35l41->index]; 238 else 239 hw_cfg->bst_ipk = -1; 240 241 property = "cirrus,boost-ind-nanohenry"; 242 ret = device_property_read_u32_array(physdev, property, values, nval); 243 if (ret == 0) 244 hw_cfg->bst_ind = values[cs35l41->index]; 245 else 246 hw_cfg->bst_ind = -1; 247 248 property = "cirrus,boost-cap-microfarad"; 249 ret = device_property_read_u32_array(physdev, property, values, nval); 250 if (ret == 0) 251 hw_cfg->bst_cap = values[cs35l41->index]; 252 else 253 hw_cfg->bst_cap = -1; 254 255 if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0) 256 hw_cfg->bst_type = CS35L41_INT_BOOST; 257 else 258 hw_cfg->bst_type = CS35L41_EXT_BOOST; 259 260 hw_cfg->valid = true; 261 put_device(physdev); 262 263 return 0; 264 265 err: 266 put_device(physdev); 267 dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); 268 269 return ret; 270 271 no_acpi_dsd: 272 /* 273 * Device CLSA0100 doesn't have _DSD so a gpiod_get by the label reset won't work. 274 * And devices created by i2c-multi-instantiate don't have their device struct pointing to 275 * the correct fwnode, so acpi_dev must be used here. 276 * And devm functions expect that the device requesting the resource has the correct 277 * fwnode. 278 */ 279 if (strncmp(hid, "CLSA0100", 8) != 0) 280 return -EINVAL; 281 282 /* check I2C address to assign the index */ 283 cs35l41->index = id == 0x40 ? 0 : 1; 284 cs35l41->hw_cfg.spk_pos = cs35l41->index; 285 cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); 286 cs35l41->hw_cfg.bst_type = CS35L41_EXT_BOOST_NO_VSPK_SWITCH; 287 cs35l41->hw_cfg.valid = true; 288 put_device(physdev); 289 290 return 0; 291 } 292 293 int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, 294 struct regmap *regmap) 295 { 296 unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; 297 struct cs35l41_hda *cs35l41; 298 int ret; 299 300 if (IS_ERR(regmap)) 301 return PTR_ERR(regmap); 302 303 cs35l41 = devm_kzalloc(dev, sizeof(*cs35l41), GFP_KERNEL); 304 if (!cs35l41) 305 return -ENOMEM; 306 307 cs35l41->dev = dev; 308 cs35l41->irq = irq; 309 cs35l41->regmap = regmap; 310 dev_set_drvdata(dev, cs35l41); 311 312 ret = cs35l41_hda_read_acpi(cs35l41, device_name, id); 313 if (ret) { 314 dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret); 315 return ret; 316 } 317 318 if (IS_ERR(cs35l41->reset_gpio)) { 319 ret = PTR_ERR(cs35l41->reset_gpio); 320 cs35l41->reset_gpio = NULL; 321 if (ret == -EBUSY) { 322 dev_info(cs35l41->dev, "Reset line busy, assuming shared reset\n"); 323 } else { 324 dev_err_probe(cs35l41->dev, ret, "Failed to get reset GPIO: %d\n", ret); 325 goto err; 326 } 327 } 328 if (cs35l41->reset_gpio) { 329 usleep_range(2000, 2100); 330 gpiod_set_value_cansleep(cs35l41->reset_gpio, 1); 331 } 332 333 usleep_range(2000, 2100); 334 335 ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status, 336 int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000); 337 if (ret) { 338 dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret); 339 goto err; 340 } 341 342 ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts); 343 if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) { 344 dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n", 345 int_sts & CS35L41_OTP_BOOT_ERR, ret); 346 ret = -EIO; 347 goto err; 348 } 349 350 ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, ®id); 351 if (ret) { 352 dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret); 353 goto err; 354 } 355 356 ret = regmap_read(cs35l41->regmap, CS35L41_REVID, ®_revid); 357 if (ret) { 358 dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret); 359 goto err; 360 } 361 362 mtl_revid = reg_revid & CS35L41_MTLREVID_MASK; 363 364 chipid = (mtl_revid % 2) ? CS35L41R_CHIP_ID : CS35L41_CHIP_ID; 365 if (regid != chipid) { 366 dev_err(cs35l41->dev, "CS35L41 Device ID (%X). Expected ID %X\n", regid, chipid); 367 ret = -ENODEV; 368 goto err; 369 } 370 371 ret = cs35l41_test_key_unlock(cs35l41->dev, cs35l41->regmap); 372 if (ret) 373 goto err; 374 375 ret = cs35l41_register_errata_patch(cs35l41->dev, cs35l41->regmap, reg_revid); 376 if (ret) 377 goto err; 378 379 ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap); 380 if (ret) { 381 dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret); 382 goto err; 383 } 384 385 ret = cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); 386 if (ret) 387 goto err; 388 389 ret = cs35l41_hda_apply_properties(cs35l41); 390 if (ret) 391 goto err; 392 393 ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops); 394 if (ret) { 395 dev_err(cs35l41->dev, "Register component failed: %d\n", ret); 396 goto err; 397 } 398 399 dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid); 400 401 return 0; 402 403 err: 404 if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) 405 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 406 gpiod_put(cs35l41->reset_gpio); 407 408 return ret; 409 } 410 EXPORT_SYMBOL_NS_GPL(cs35l41_hda_probe, SND_HDA_SCODEC_CS35L41); 411 412 void cs35l41_hda_remove(struct device *dev) 413 { 414 struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); 415 416 component_del(cs35l41->dev, &cs35l41_hda_comp_ops); 417 418 if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type)) 419 gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); 420 gpiod_put(cs35l41->reset_gpio); 421 } 422 EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); 423 424 MODULE_DESCRIPTION("CS35L41 HDA Driver"); 425 MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); 426 MODULE_LICENSE("GPL"); 427