Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mfd: Add initial WM8958 support

The WM8958 is a derivative of the WM8994 which is register compatible
with the addition of some extra features, mostly in the CODEC side.
The major change visible at the MFD level is that rather than a single
DBVDD supply we now have three separate DBVDDs so we must request and
enable a different set of supplies.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>

+82 -19
+74 -19
drivers/mfd/wm8994-core.c
··· 218 218 "SPKVDD2", 219 219 }; 220 220 221 + static const char *wm8958_main_supplies[] = { 222 + "DBVDD1", 223 + "DBVDD2", 224 + "DBVDD3", 225 + "DCVDD", 226 + "AVDD1", 227 + "AVDD2", 228 + "CPVDD", 229 + "SPKVDD1", 230 + "SPKVDD2", 231 + }; 232 + 221 233 #ifdef CONFIG_PM 222 234 static int wm8994_device_suspend(struct device *dev) 223 235 { ··· 251 239 if (ret < 0) 252 240 dev_err(dev, "Failed to save LDO registers: %d\n", ret); 253 241 254 - ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 242 + ret = regulator_bulk_disable(wm8994->num_supplies, 255 243 wm8994->supplies); 256 244 if (ret != 0) { 257 245 dev_err(dev, "Failed to disable supplies: %d\n", ret); ··· 266 254 struct wm8994 *wm8994 = dev_get_drvdata(dev); 267 255 int ret; 268 256 269 - ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), 257 + ret = regulator_bulk_enable(wm8994->num_supplies, 270 258 wm8994->supplies); 271 259 if (ret != 0) { 272 260 dev_err(dev, "Failed to enable supplies: %d\n", ret); ··· 317 305 /* 318 306 * Instantiate the generic non-control parts of the device. 319 307 */ 320 - static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) 308 + static int wm8994_device_init(struct wm8994 *wm8994, int irq) 321 309 { 322 310 struct wm8994_pdata *pdata = wm8994->dev->platform_data; 311 + const char *devname; 323 312 int ret, i; 324 313 325 314 mutex_init(&wm8994->io_lock); ··· 336 323 goto err; 337 324 } 338 325 326 + switch (wm8994->type) { 327 + case WM8994: 328 + wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); 329 + break; 330 + case WM8958: 331 + wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies); 332 + break; 333 + default: 334 + BUG(); 335 + return -EINVAL; 336 + } 337 + 339 338 wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * 340 - ARRAY_SIZE(wm8994_main_supplies), 339 + wm8994->num_supplies, 341 340 GFP_KERNEL); 342 341 if (!wm8994->supplies) { 343 342 ret = -ENOMEM; 344 343 goto err; 345 344 } 346 345 347 - for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) 348 - wm8994->supplies[i].supply = wm8994_main_supplies[i]; 349 - 350 - ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies), 346 + switch (wm8994->type) { 347 + case WM8994: 348 + for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) 349 + wm8994->supplies[i].supply = wm8994_main_supplies[i]; 350 + break; 351 + case WM8958: 352 + for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++) 353 + wm8994->supplies[i].supply = wm8958_main_supplies[i]; 354 + break; 355 + default: 356 + BUG(); 357 + return -EINVAL; 358 + } 359 + 360 + ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, 351 361 wm8994->supplies); 352 362 if (ret != 0) { 353 363 dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); 354 364 goto err_supplies; 355 365 } 356 366 357 - ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), 367 + ret = regulator_bulk_enable(wm8994->num_supplies, 358 368 wm8994->supplies); 359 369 if (ret != 0) { 360 370 dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); ··· 389 353 dev_err(wm8994->dev, "Failed to read ID register\n"); 390 354 goto err_enable; 391 355 } 392 - if (ret != 0x8994) { 356 + switch (ret) { 357 + case 0x8994: 358 + devname = "WM8994"; 359 + if (wm8994->type != WM8994) 360 + dev_warn(wm8994->dev, "Device registered as type %d\n", 361 + wm8994->type); 362 + wm8994->type = WM8994; 363 + break; 364 + case 0x8958: 365 + devname = "WM8958"; 366 + if (wm8994->type != WM8958) 367 + dev_warn(wm8994->dev, "Device registered as type %d\n", 368 + wm8994->type); 369 + wm8994->type = WM8958; 370 + break; 371 + default: 393 372 dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", 394 373 ret); 395 374 ret = -EINVAL; ··· 421 370 switch (ret) { 422 371 case 0: 423 372 case 1: 424 - dev_warn(wm8994->dev, "revision %c not fully supported\n", 425 - 'A' + ret); 373 + if (wm8994->type == WM8994) 374 + dev_warn(wm8994->dev, 375 + "revision %c not fully supported\n", 376 + 'A' + ret); 426 377 break; 427 378 default: 428 - dev_info(wm8994->dev, "revision %c\n", 'A' + ret); 429 379 break; 430 380 } 431 381 382 + dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret); 432 383 433 384 if (pdata) { 434 385 wm8994->irq_base = pdata->irq_base; ··· 476 423 err_irq: 477 424 wm8994_irq_exit(wm8994); 478 425 err_enable: 479 - regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 426 + regulator_bulk_disable(wm8994->num_supplies, 480 427 wm8994->supplies); 481 428 err_get: 482 - regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); 429 + regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 483 430 err_supplies: 484 431 kfree(wm8994->supplies); 485 432 err: ··· 492 439 { 493 440 mfd_remove_devices(wm8994->dev); 494 441 wm8994_irq_exit(wm8994); 495 - regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), 442 + regulator_bulk_disable(wm8994->num_supplies, 496 443 wm8994->supplies); 497 - regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); 444 + regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); 498 445 kfree(wm8994->supplies); 499 446 kfree(wm8994); 500 447 } ··· 559 506 wm8994->read_dev = wm8994_i2c_read_device; 560 507 wm8994->write_dev = wm8994_i2c_write_device; 561 508 wm8994->irq = i2c->irq; 509 + wm8994->type = id->driver_data; 562 510 563 - return wm8994_device_init(wm8994, id->driver_data, i2c->irq); 511 + return wm8994_device_init(wm8994, i2c->irq); 564 512 } 565 513 566 514 static int wm8994_i2c_remove(struct i2c_client *i2c) ··· 589 535 #endif 590 536 591 537 static const struct i2c_device_id wm8994_i2c_id[] = { 592 - { "wm8994", 0 }, 538 + { "wm8994", WM8994 }, 539 + { "wm8958", WM8958 }, 593 540 { } 594 541 }; 595 542 MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
+8
include/linux/mfd/wm8994/core.h
··· 17 17 18 18 #include <linux/interrupt.h> 19 19 20 + enum wm8994_type { 21 + WM8994 = 0, 22 + WM8958 = 1, 23 + }; 24 + 20 25 struct regulator_dev; 21 26 struct regulator_bulk_data; 22 27 ··· 53 48 struct mutex io_lock; 54 49 struct mutex irq_lock; 55 50 51 + enum wm8994_type type; 52 + 56 53 struct device *dev; 57 54 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 58 55 int bytes, void *dest); ··· 75 68 u16 gpio_regs[WM8994_NUM_GPIO_REGS]; 76 69 77 70 struct regulator_dev *dbvdd; 71 + int num_supplies; 78 72 struct regulator_bulk_data *supplies; 79 73 }; 80 74