diff options
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-rw-r--r-- | sound/soc/codecs/wm8904.c | 208 |
1 files changed, 60 insertions, 148 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index f7dcabf6283c..33be84e506ea 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -31,9 +31,6 @@ | |||
31 | 31 | ||
32 | #include "wm8904.h" | 32 | #include "wm8904.h" |
33 | 33 | ||
34 | static struct snd_soc_codec *wm8904_codec; | ||
35 | struct snd_soc_codec_device soc_codec_dev_wm8904; | ||
36 | |||
37 | enum wm8904_type { | 34 | enum wm8904_type { |
38 | WM8904, | 35 | WM8904, |
39 | WM8912, | 36 | WM8912, |
@@ -52,10 +49,11 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { | |||
52 | 49 | ||
53 | /* codec private data */ | 50 | /* codec private data */ |
54 | struct wm8904_priv { | 51 | struct wm8904_priv { |
55 | struct snd_soc_codec codec; | 52 | |
56 | u16 reg_cache[WM8904_MAX_REGISTER + 1]; | 53 | u16 reg_cache[WM8904_MAX_REGISTER + 1]; |
57 | 54 | ||
58 | enum wm8904_type devtype; | 55 | enum wm8904_type devtype; |
56 | void *control_data; | ||
59 | 57 | ||
60 | struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; | 58 | struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; |
61 | 59 | ||
@@ -689,7 +687,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
689 | struct snd_ctl_elem_value *ucontrol) | 687 | struct snd_ctl_elem_value *ucontrol) |
690 | { | 688 | { |
691 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 689 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
692 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 690 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
693 | struct wm8904_pdata *pdata = wm8904->pdata; | 691 | struct wm8904_pdata *pdata = wm8904->pdata; |
694 | int value = ucontrol->value.integer.value[0]; | 692 | int value = ucontrol->value.integer.value[0]; |
695 | 693 | ||
@@ -760,7 +758,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
760 | struct snd_ctl_elem_value *ucontrol) | 758 | struct snd_ctl_elem_value *ucontrol) |
761 | { | 759 | { |
762 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 760 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
763 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 761 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
764 | struct wm8904_pdata *pdata = wm8904->pdata; | 762 | struct wm8904_pdata *pdata = wm8904->pdata; |
765 | int value = ucontrol->value.integer.value[0]; | 763 | int value = ucontrol->value.integer.value[0]; |
766 | 764 | ||
@@ -2218,8 +2216,8 @@ static struct snd_soc_dai_ops wm8904_dai_ops = { | |||
2218 | .digital_mute = wm8904_digital_mute, | 2216 | .digital_mute = wm8904_digital_mute, |
2219 | }; | 2217 | }; |
2220 | 2218 | ||
2221 | struct snd_soc_dai wm8904_dai = { | 2219 | static struct snd_soc_dai_driver wm8904_dai = { |
2222 | .name = "WM8904", | 2220 | .name = "wm8904-hifi", |
2223 | .playback = { | 2221 | .playback = { |
2224 | .stream_name = "Playback", | 2222 | .stream_name = "Playback", |
2225 | .channels_min = 2, | 2223 | .channels_min = 2, |
@@ -2237,24 +2235,17 @@ struct snd_soc_dai wm8904_dai = { | |||
2237 | .ops = &wm8904_dai_ops, | 2235 | .ops = &wm8904_dai_ops, |
2238 | .symmetric_rates = 1, | 2236 | .symmetric_rates = 1, |
2239 | }; | 2237 | }; |
2240 | EXPORT_SYMBOL_GPL(wm8904_dai); | ||
2241 | 2238 | ||
2242 | #ifdef CONFIG_PM | 2239 | #ifdef CONFIG_PM |
2243 | static int wm8904_suspend(struct platform_device *pdev, pm_message_t state) | 2240 | static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state) |
2244 | { | 2241 | { |
2245 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
2246 | struct snd_soc_codec *codec = socdev->card->codec; | ||
2247 | |||
2248 | wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2242 | wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2249 | 2243 | ||
2250 | return 0; | 2244 | return 0; |
2251 | } | 2245 | } |
2252 | 2246 | ||
2253 | static int wm8904_resume(struct platform_device *pdev) | 2247 | static int wm8904_resume(struct snd_soc_codec *codec) |
2254 | { | 2248 | { |
2255 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
2256 | struct snd_soc_codec *codec = socdev->card->codec; | ||
2257 | |||
2258 | wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 2249 | wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
2259 | 2250 | ||
2260 | return 0; | 2251 | return 0; |
@@ -2264,9 +2255,9 @@ static int wm8904_resume(struct platform_device *pdev) | |||
2264 | #define wm8904_resume NULL | 2255 | #define wm8904_resume NULL |
2265 | #endif | 2256 | #endif |
2266 | 2257 | ||
2267 | static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) | 2258 | static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) |
2268 | { | 2259 | { |
2269 | struct snd_soc_codec *codec = &wm8904->codec; | 2260 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2270 | struct wm8904_pdata *pdata = wm8904->pdata; | 2261 | struct wm8904_pdata *pdata = wm8904->pdata; |
2271 | struct snd_kcontrol_new control = | 2262 | struct snd_kcontrol_new control = |
2272 | SOC_ENUM_EXT("EQ Mode", | 2263 | SOC_ENUM_EXT("EQ Mode", |
@@ -2315,20 +2306,20 @@ static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904) | |||
2315 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; | 2306 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; |
2316 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; | 2307 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; |
2317 | 2308 | ||
2318 | ret = snd_soc_add_controls(&wm8904->codec, &control, 1); | 2309 | ret = snd_soc_add_controls(codec, &control, 1); |
2319 | if (ret != 0) | 2310 | if (ret != 0) |
2320 | dev_err(wm8904->codec.dev, | 2311 | dev_err(codec->dev, |
2321 | "Failed to add ReTune Mobile control: %d\n", ret); | 2312 | "Failed to add ReTune Mobile control: %d\n", ret); |
2322 | } | 2313 | } |
2323 | 2314 | ||
2324 | static void wm8904_handle_pdata(struct wm8904_priv *wm8904) | 2315 | static void wm8904_handle_pdata(struct snd_soc_codec *codec) |
2325 | { | 2316 | { |
2326 | struct snd_soc_codec *codec = &wm8904->codec; | 2317 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2327 | struct wm8904_pdata *pdata = wm8904->pdata; | 2318 | struct wm8904_pdata *pdata = wm8904->pdata; |
2328 | int ret, i; | 2319 | int ret, i; |
2329 | 2320 | ||
2330 | if (!pdata) { | 2321 | if (!pdata) { |
2331 | snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, | 2322 | snd_soc_add_controls(codec, wm8904_eq_controls, |
2332 | ARRAY_SIZE(wm8904_eq_controls)); | 2323 | ARRAY_SIZE(wm8904_eq_controls)); |
2333 | return; | 2324 | return; |
2334 | } | 2325 | } |
@@ -2344,7 +2335,7 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904) | |||
2344 | wm8904->drc_texts = kmalloc(sizeof(char *) | 2335 | wm8904->drc_texts = kmalloc(sizeof(char *) |
2345 | * pdata->num_drc_cfgs, GFP_KERNEL); | 2336 | * pdata->num_drc_cfgs, GFP_KERNEL); |
2346 | if (!wm8904->drc_texts) { | 2337 | if (!wm8904->drc_texts) { |
2347 | dev_err(wm8904->codec.dev, | 2338 | dev_err(codec->dev, |
2348 | "Failed to allocate %d DRC config texts\n", | 2339 | "Failed to allocate %d DRC config texts\n", |
2349 | pdata->num_drc_cfgs); | 2340 | pdata->num_drc_cfgs); |
2350 | return; | 2341 | return; |
@@ -2356,9 +2347,9 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904) | |||
2356 | wm8904->drc_enum.max = pdata->num_drc_cfgs; | 2347 | wm8904->drc_enum.max = pdata->num_drc_cfgs; |
2357 | wm8904->drc_enum.texts = wm8904->drc_texts; | 2348 | wm8904->drc_enum.texts = wm8904->drc_texts; |
2358 | 2349 | ||
2359 | ret = snd_soc_add_controls(&wm8904->codec, &control, 1); | 2350 | ret = snd_soc_add_controls(codec, &control, 1); |
2360 | if (ret != 0) | 2351 | if (ret != 0) |
2361 | dev_err(wm8904->codec.dev, | 2352 | dev_err(codec->dev, |
2362 | "Failed to add DRC mode control: %d\n", ret); | 2353 | "Failed to add DRC mode control: %d\n", ret); |
2363 | 2354 | ||
2364 | wm8904_set_drc(codec); | 2355 | wm8904_set_drc(codec); |
@@ -2368,89 +2359,19 @@ static void wm8904_handle_pdata(struct wm8904_priv *wm8904) | |||
2368 | pdata->num_retune_mobile_cfgs); | 2359 | pdata->num_retune_mobile_cfgs); |
2369 | 2360 | ||
2370 | if (pdata->num_retune_mobile_cfgs) | 2361 | if (pdata->num_retune_mobile_cfgs) |
2371 | wm8904_handle_retune_mobile_pdata(wm8904); | 2362 | wm8904_handle_retune_mobile_pdata(codec); |
2372 | else | 2363 | else |
2373 | snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls, | 2364 | snd_soc_add_controls(codec, wm8904_eq_controls, |
2374 | ARRAY_SIZE(wm8904_eq_controls)); | 2365 | ARRAY_SIZE(wm8904_eq_controls)); |
2375 | } | 2366 | } |
2376 | 2367 | ||
2377 | static int wm8904_probe(struct platform_device *pdev) | ||
2378 | { | ||
2379 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
2380 | struct snd_soc_codec *codec; | ||
2381 | int ret = 0; | ||
2382 | |||
2383 | if (wm8904_codec == NULL) { | ||
2384 | dev_err(&pdev->dev, "Codec device not registered\n"); | ||
2385 | return -ENODEV; | ||
2386 | } | ||
2387 | 2368 | ||
2388 | socdev->card->codec = wm8904_codec; | 2369 | static int wm8904_probe(struct snd_soc_codec *codec) |
2389 | codec = wm8904_codec; | ||
2390 | |||
2391 | /* register pcms */ | ||
2392 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
2393 | if (ret < 0) { | ||
2394 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); | ||
2395 | goto pcm_err; | ||
2396 | } | ||
2397 | |||
2398 | wm8904_handle_pdata(snd_soc_codec_get_drvdata(codec)); | ||
2399 | |||
2400 | wm8904_add_widgets(codec); | ||
2401 | |||
2402 | return ret; | ||
2403 | |||
2404 | pcm_err: | ||
2405 | return ret; | ||
2406 | } | ||
2407 | |||
2408 | static int wm8904_remove(struct platform_device *pdev) | ||
2409 | { | ||
2410 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
2411 | |||
2412 | snd_soc_free_pcms(socdev); | ||
2413 | snd_soc_dapm_free(socdev); | ||
2414 | |||
2415 | return 0; | ||
2416 | } | ||
2417 | |||
2418 | struct snd_soc_codec_device soc_codec_dev_wm8904 = { | ||
2419 | .probe = wm8904_probe, | ||
2420 | .remove = wm8904_remove, | ||
2421 | .suspend = wm8904_suspend, | ||
2422 | .resume = wm8904_resume, | ||
2423 | }; | ||
2424 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904); | ||
2425 | |||
2426 | static int wm8904_register(struct wm8904_priv *wm8904, | ||
2427 | enum snd_soc_control_type control) | ||
2428 | { | 2370 | { |
2371 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | ||
2429 | struct wm8904_pdata *pdata = wm8904->pdata; | 2372 | struct wm8904_pdata *pdata = wm8904->pdata; |
2430 | int ret; | 2373 | int ret, i; |
2431 | struct snd_soc_codec *codec = &wm8904->codec; | ||
2432 | int i; | ||
2433 | |||
2434 | if (wm8904_codec) { | ||
2435 | dev_err(codec->dev, "Another WM8904 is registered\n"); | ||
2436 | ret = -EINVAL; | ||
2437 | goto err; | ||
2438 | } | ||
2439 | 2374 | ||
2440 | mutex_init(&codec->mutex); | ||
2441 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
2442 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
2443 | |||
2444 | snd_soc_codec_set_drvdata(codec, wm8904); | ||
2445 | codec->name = "WM8904"; | ||
2446 | codec->owner = THIS_MODULE; | ||
2447 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
2448 | codec->set_bias_level = wm8904_set_bias_level; | ||
2449 | codec->dai = &wm8904_dai; | ||
2450 | codec->num_dai = 1; | ||
2451 | codec->reg_cache_size = WM8904_MAX_REGISTER; | ||
2452 | codec->reg_cache = &wm8904->reg_cache; | ||
2453 | codec->volatile_register = wm8904_volatile_register; | ||
2454 | codec->cache_sync = 1; | 2375 | codec->cache_sync = 1; |
2455 | codec->idle_bias_off = 1; | 2376 | codec->idle_bias_off = 1; |
2456 | 2377 | ||
@@ -2463,16 +2384,13 @@ static int wm8904_register(struct wm8904_priv *wm8904, | |||
2463 | default: | 2384 | default: |
2464 | dev_err(codec->dev, "Unknown device type %d\n", | 2385 | dev_err(codec->dev, "Unknown device type %d\n", |
2465 | wm8904->devtype); | 2386 | wm8904->devtype); |
2466 | ret = -EINVAL; | 2387 | return -EINVAL; |
2467 | goto err; | ||
2468 | } | 2388 | } |
2469 | 2389 | ||
2470 | memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); | 2390 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
2471 | |||
2472 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); | ||
2473 | if (ret != 0) { | 2391 | if (ret != 0) { |
2474 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 2392 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
2475 | goto err; | 2393 | return ret; |
2476 | } | 2394 | } |
2477 | 2395 | ||
2478 | for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) | 2396 | for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++) |
@@ -2482,7 +2400,7 @@ static int wm8904_register(struct wm8904_priv *wm8904, | |||
2482 | wm8904->supplies); | 2400 | wm8904->supplies); |
2483 | if (ret != 0) { | 2401 | if (ret != 0) { |
2484 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 2402 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
2485 | goto err; | 2403 | return ret; |
2486 | } | 2404 | } |
2487 | 2405 | ||
2488 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), | 2406 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), |
@@ -2517,8 +2435,6 @@ static int wm8904_register(struct wm8904_priv *wm8904, | |||
2517 | goto err_enable; | 2435 | goto err_enable; |
2518 | } | 2436 | } |
2519 | 2437 | ||
2520 | wm8904_dai.dev = codec->dev; | ||
2521 | |||
2522 | /* Change some default settings - latch VU and enable ZC */ | 2438 | /* Change some default settings - latch VU and enable ZC */ |
2523 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; | 2439 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; |
2524 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; | 2440 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; |
@@ -2563,72 +2479,68 @@ static int wm8904_register(struct wm8904_priv *wm8904, | |||
2563 | /* Bias level configuration will have done an extra enable */ | 2479 | /* Bias level configuration will have done an extra enable */ |
2564 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | 2480 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); |
2565 | 2481 | ||
2566 | wm8904_codec = codec; | 2482 | wm8904_handle_pdata(codec); |
2567 | 2483 | ||
2568 | ret = snd_soc_register_codec(codec); | 2484 | wm8904_add_widgets(codec); |
2569 | if (ret != 0) { | ||
2570 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
2571 | goto err_enable; | ||
2572 | } | ||
2573 | |||
2574 | ret = snd_soc_register_dai(&wm8904_dai); | ||
2575 | if (ret != 0) { | ||
2576 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | ||
2577 | goto err_codec; | ||
2578 | } | ||
2579 | 2485 | ||
2580 | return 0; | 2486 | return 0; |
2581 | 2487 | ||
2582 | err_codec: | ||
2583 | snd_soc_unregister_codec(codec); | ||
2584 | err_enable: | 2488 | err_enable: |
2585 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | 2489 | regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); |
2586 | err_get: | 2490 | err_get: |
2587 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | 2491 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); |
2588 | err: | ||
2589 | kfree(wm8904); | ||
2590 | return ret; | 2492 | return ret; |
2591 | } | 2493 | } |
2592 | 2494 | ||
2593 | static void wm8904_unregister(struct wm8904_priv *wm8904) | 2495 | static int wm8904_remove(struct snd_soc_codec *codec) |
2594 | { | 2496 | { |
2595 | wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF); | 2497 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2498 | |||
2499 | wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2596 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | 2500 | regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); |
2597 | snd_soc_unregister_dai(&wm8904_dai); | 2501 | |
2598 | snd_soc_unregister_codec(&wm8904->codec); | 2502 | return 0; |
2599 | kfree(wm8904); | ||
2600 | wm8904_codec = NULL; | ||
2601 | } | 2503 | } |
2602 | 2504 | ||
2505 | static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { | ||
2506 | .probe = wm8904_probe, | ||
2507 | .remove = wm8904_remove, | ||
2508 | .suspend = wm8904_suspend, | ||
2509 | .resume = wm8904_resume, | ||
2510 | .set_bias_level = wm8904_set_bias_level, | ||
2511 | .reg_cache_size = ARRAY_SIZE(wm8904_reg), | ||
2512 | .reg_word_size = sizeof(u16), | ||
2513 | .reg_cache_default = wm8904_reg, | ||
2514 | .volatile_register = wm8904_volatile_register, | ||
2515 | }; | ||
2516 | |||
2603 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 2517 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
2604 | static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | 2518 | static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, |
2605 | const struct i2c_device_id *id) | 2519 | const struct i2c_device_id *id) |
2606 | { | 2520 | { |
2607 | struct wm8904_priv *wm8904; | 2521 | struct wm8904_priv *wm8904; |
2608 | struct snd_soc_codec *codec; | 2522 | int ret; |
2609 | 2523 | ||
2610 | wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); | 2524 | wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); |
2611 | if (wm8904 == NULL) | 2525 | if (wm8904 == NULL) |
2612 | return -ENOMEM; | 2526 | return -ENOMEM; |
2613 | 2527 | ||
2614 | codec = &wm8904->codec; | ||
2615 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
2616 | |||
2617 | wm8904->devtype = id->driver_data; | 2528 | wm8904->devtype = id->driver_data; |
2618 | |||
2619 | i2c_set_clientdata(i2c, wm8904); | 2529 | i2c_set_clientdata(i2c, wm8904); |
2620 | codec->control_data = i2c; | 2530 | wm8904->control_data = i2c; |
2621 | wm8904->pdata = i2c->dev.platform_data; | 2531 | wm8904->pdata = i2c->dev.platform_data; |
2622 | 2532 | ||
2623 | codec->dev = &i2c->dev; | 2533 | ret = snd_soc_register_codec(&i2c->dev, |
2624 | 2534 | &soc_codec_dev_wm8904, &wm8904_dai, 1); | |
2625 | return wm8904_register(wm8904, SND_SOC_I2C); | 2535 | if (ret < 0) |
2536 | kfree(wm8904); | ||
2537 | return ret; | ||
2626 | } | 2538 | } |
2627 | 2539 | ||
2628 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) | 2540 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) |
2629 | { | 2541 | { |
2630 | struct wm8904_priv *wm8904 = i2c_get_clientdata(client); | 2542 | snd_soc_unregister_codec(&client->dev); |
2631 | wm8904_unregister(wm8904); | 2543 | kfree(i2c_get_clientdata(client)); |
2632 | return 0; | 2544 | return 0; |
2633 | } | 2545 | } |
2634 | 2546 | ||
@@ -2641,7 +2553,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); | |||
2641 | 2553 | ||
2642 | static struct i2c_driver wm8904_i2c_driver = { | 2554 | static struct i2c_driver wm8904_i2c_driver = { |
2643 | .driver = { | 2555 | .driver = { |
2644 | .name = "WM8904", | 2556 | .name = "wm8904-codec", |
2645 | .owner = THIS_MODULE, | 2557 | .owner = THIS_MODULE, |
2646 | }, | 2558 | }, |
2647 | .probe = wm8904_i2c_probe, | 2559 | .probe = wm8904_i2c_probe, |
@@ -2652,15 +2564,15 @@ static struct i2c_driver wm8904_i2c_driver = { | |||
2652 | 2564 | ||
2653 | static int __init wm8904_modinit(void) | 2565 | static int __init wm8904_modinit(void) |
2654 | { | 2566 | { |
2655 | int ret; | 2567 | int ret = 0; |
2656 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 2568 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
2657 | ret = i2c_add_driver(&wm8904_i2c_driver); | 2569 | ret = i2c_add_driver(&wm8904_i2c_driver); |
2658 | if (ret != 0) { | 2570 | if (ret != 0) { |
2659 | printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n", | 2571 | printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", |
2660 | ret); | 2572 | ret); |
2661 | } | 2573 | } |
2662 | #endif | 2574 | #endif |
2663 | return 0; | 2575 | return ret; |
2664 | } | 2576 | } |
2665 | module_init(wm8904_modinit); | 2577 | module_init(wm8904_modinit); |
2666 | 2578 | ||