Commit | Line | Data |
---|---|---|
2dcf9fb9 GG |
1 | /* |
2 | * ads117x.c -- Driver for ads1174/8 ADC chips | |
3 | * | |
4 | * Copyright 2009 ShotSpotter Inc. | |
5 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2 of the License, or (at your | |
10 | * option) any later version. | |
11 | */ | |
12 | ||
13 | #include <linux/kernel.h> | |
14 | #include <linux/init.h> | |
15 | #include <linux/device.h> | |
16 | #include <sound/core.h> | |
17 | #include <sound/pcm.h> | |
18 | #include <sound/initval.h> | |
19 | #include <sound/soc.h> | |
20 | ||
21 | #include "ads117x.h" | |
22 | ||
23 | #define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000) | |
24 | ||
25 | #define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) | |
26 | ||
27 | struct snd_soc_dai ads117x_dai = { | |
28 | /* ADC */ | |
29 | .name = "ADS117X ADC", | |
30 | .id = 1, | |
31 | .capture = { | |
32 | .stream_name = "Capture", | |
33 | .channels_min = 1, | |
34 | .channels_max = 32, | |
35 | .rates = ADS117X_RATES, | |
36 | .formats = ADS117X_FORMATS,}, | |
37 | }; | |
38 | EXPORT_SYMBOL_GPL(ads117x_dai); | |
39 | ||
40 | /* | |
41 | * initialise the ads117x driver | |
42 | */ | |
43 | static int ads117x_init(struct snd_soc_device *socdev) | |
44 | { | |
45 | struct snd_soc_codec *codec = socdev->card->codec; | |
46 | int ret = 0; | |
47 | ||
48 | codec->name = "ADS117X"; | |
49 | codec->owner = THIS_MODULE; | |
50 | codec->dai = &ads117x_dai; | |
51 | codec->num_dai = 1; | |
52 | ||
53 | /* register pcms */ | |
54 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | |
55 | if (ret < 0) { | |
56 | printk(KERN_ERR "ads117x: failed to create pcms\n"); | |
57 | return ret; | |
58 | } | |
59 | ||
60 | ret = snd_soc_init_card(socdev); | |
61 | if (ret < 0) { | |
62 | printk(KERN_ERR "ads117x: failed to register card\n"); | |
63 | goto card_err; | |
64 | } | |
65 | return ret; | |
66 | ||
67 | card_err: | |
68 | snd_soc_free_pcms(socdev); | |
69 | return ret; | |
70 | } | |
71 | ||
72 | static int ads117x_probe(struct platform_device *pdev) | |
73 | { | |
74 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | |
75 | struct snd_soc_codec *codec; | |
76 | int ret; | |
77 | ||
78 | pr_info("ads117x ADC\n"); | |
79 | ||
80 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | |
81 | if (codec == NULL) | |
82 | return -ENOMEM; | |
83 | ||
84 | socdev->card->codec = codec; | |
85 | mutex_init(&codec->mutex); | |
86 | INIT_LIST_HEAD(&codec->dapm_widgets); | |
87 | INIT_LIST_HEAD(&codec->dapm_paths); | |
88 | ||
89 | ret = ads117x_init(socdev); | |
90 | if (ret != 0) | |
91 | kfree(codec); | |
92 | ||
93 | return ret; | |
94 | } | |
95 | ||
96 | static int ads117x_remove(struct platform_device *pdev) | |
97 | { | |
98 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | |
99 | struct snd_soc_codec *codec = socdev->card->codec; | |
100 | ||
101 | snd_soc_free_pcms(socdev); | |
102 | kfree(codec); | |
103 | ||
104 | return 0; | |
105 | } | |
106 | ||
107 | struct snd_soc_codec_device soc_codec_dev_ads117x = { | |
108 | .probe = ads117x_probe, | |
109 | .remove = ads117x_remove, | |
110 | }; | |
111 | EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x); | |
112 | ||
113 | static int __init ads117x_modinit(void) | |
114 | { | |
115 | return snd_soc_register_dai(&ads117x_dai); | |
116 | } | |
117 | module_init(ads117x_modinit); | |
118 | ||
119 | static void __exit ads117x_exit(void) | |
120 | { | |
121 | snd_soc_unregister_dai(&ads117x_dai); | |
122 | } | |
123 | module_exit(ads117x_exit); | |
124 | ||
125 | MODULE_DESCRIPTION("ASoC ads117x driver"); | |
126 | MODULE_AUTHOR("Graeme Gregory"); | |
127 | MODULE_LICENSE("GPL"); |