diff options
author | Paul Mackerras <paulus@samba.org> | 2006-07-31 20:37:25 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-07-31 20:37:25 -0400 |
commit | 57cad8084e0837e0f2c97da789ec9b3f36809be9 (patch) | |
tree | e9c790afb4286f78cb08d9664f58baa7e876fe55 /sound/aoa | |
parent | cb18bd40030c879cd93fef02fd579f74dbab473d (diff) | |
parent | 49b1e3ea19b1c95c2f012b8331ffb3b169e4c042 (diff) |
Merge branch 'merge'
Diffstat (limited to 'sound/aoa')
-rw-r--r-- | sound/aoa/Makefile | 4 | ||||
-rw-r--r-- | sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h | 134 | ||||
-rw-r--r-- | sound/aoa/codecs/snd-aoa-codec-tas.c | 331 | ||||
-rw-r--r-- | sound/aoa/codecs/snd-aoa-codec-tas.h | 8 | ||||
-rw-r--r-- | sound/aoa/core/snd-aoa-gpio-pmf.c | 14 | ||||
-rw-r--r-- | sound/aoa/fabrics/snd-aoa-fabric-layout.c | 26 | ||||
-rw-r--r-- | sound/aoa/soundbus/core.c | 22 | ||||
-rw-r--r-- | sound/aoa/soundbus/i2sbus/i2sbus-control.c | 79 | ||||
-rw-r--r-- | sound/aoa/soundbus/i2sbus/i2sbus-control.h | 37 | ||||
-rw-r--r-- | sound/aoa/soundbus/i2sbus/i2sbus-core.c | 129 | ||||
-rw-r--r-- | sound/aoa/soundbus/i2sbus/i2sbus.h | 18 |
11 files changed, 645 insertions, 157 deletions
diff --git a/sound/aoa/Makefile b/sound/aoa/Makefile index d8de3e7df48d..a8c037f908f8 100644 --- a/sound/aoa/Makefile +++ b/sound/aoa/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_SND_AOA) += core/ | 1 | obj-$(CONFIG_SND_AOA) += core/ |
2 | obj-$(CONFIG_SND_AOA) += codecs/ | ||
3 | obj-$(CONFIG_SND_AOA) += fabrics/ | ||
4 | obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/ | 2 | obj-$(CONFIG_SND_AOA_SOUNDBUS) += soundbus/ |
3 | obj-$(CONFIG_SND_AOA) += fabrics/ | ||
4 | obj-$(CONFIG_SND_AOA) += codecs/ | ||
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h new file mode 100644 index 000000000000..69b61136fd54 --- /dev/null +++ b/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * This file is only included exactly once! | ||
3 | * | ||
4 | * The tables here are derived from the tas3004 datasheet, | ||
5 | * modulo typo corrections and some smoothing... | ||
6 | */ | ||
7 | |||
8 | #define TAS3004_TREBLE_MIN 0 | ||
9 | #define TAS3004_TREBLE_MAX 72 | ||
10 | #define TAS3004_BASS_MIN 0 | ||
11 | #define TAS3004_BASS_MAX 72 | ||
12 | #define TAS3004_TREBLE_ZERO 36 | ||
13 | #define TAS3004_BASS_ZERO 36 | ||
14 | |||
15 | static u8 tas3004_treble_table[] = { | ||
16 | 150, /* -18 dB */ | ||
17 | 149, | ||
18 | 148, | ||
19 | 147, | ||
20 | 146, | ||
21 | 145, | ||
22 | 144, | ||
23 | 143, | ||
24 | 142, | ||
25 | 141, | ||
26 | 140, | ||
27 | 139, | ||
28 | 138, | ||
29 | 137, | ||
30 | 136, | ||
31 | 135, | ||
32 | 134, | ||
33 | 133, | ||
34 | 132, | ||
35 | 131, | ||
36 | 130, | ||
37 | 129, | ||
38 | 128, | ||
39 | 127, | ||
40 | 126, | ||
41 | 125, | ||
42 | 124, | ||
43 | 123, | ||
44 | 122, | ||
45 | 121, | ||
46 | 120, | ||
47 | 119, | ||
48 | 118, | ||
49 | 117, | ||
50 | 116, | ||
51 | 115, | ||
52 | 114, /* 0 dB */ | ||
53 | 113, | ||
54 | 112, | ||
55 | 111, | ||
56 | 109, | ||
57 | 108, | ||
58 | 107, | ||
59 | 105, | ||
60 | 104, | ||
61 | 103, | ||
62 | 101, | ||
63 | 99, | ||
64 | 98, | ||
65 | 96, | ||
66 | 93, | ||
67 | 91, | ||
68 | 89, | ||
69 | 86, | ||
70 | 83, | ||
71 | 81, | ||
72 | 77, | ||
73 | 74, | ||
74 | 71, | ||
75 | 67, | ||
76 | 63, | ||
77 | 59, | ||
78 | 54, | ||
79 | 49, | ||
80 | 44, | ||
81 | 38, | ||
82 | 32, | ||
83 | 26, | ||
84 | 19, | ||
85 | 10, | ||
86 | 4, | ||
87 | 2, | ||
88 | 1, /* +18 dB */ | ||
89 | }; | ||
90 | |||
91 | static inline u8 tas3004_treble(int idx) | ||
92 | { | ||
93 | return tas3004_treble_table[idx]; | ||
94 | } | ||
95 | |||
96 | /* I only save the difference here to the treble table | ||
97 | * so that the binary is smaller... | ||
98 | * I have also ignored completely differences of | ||
99 | * +/- 1 | ||
100 | */ | ||
101 | static s8 tas3004_bass_diff_to_treble[] = { | ||
102 | 2, /* 7 dB, offset 50 */ | ||
103 | 2, | ||
104 | 2, | ||
105 | 2, | ||
106 | 2, | ||
107 | 1, | ||
108 | 2, | ||
109 | 2, | ||
110 | 2, | ||
111 | 3, | ||
112 | 4, | ||
113 | 4, | ||
114 | 5, | ||
115 | 6, | ||
116 | 7, | ||
117 | 8, | ||
118 | 9, | ||
119 | 10, | ||
120 | 11, | ||
121 | 14, | ||
122 | 13, | ||
123 | 8, | ||
124 | 1, /* 18 dB */ | ||
125 | }; | ||
126 | |||
127 | static inline u8 tas3004_bass(int idx) | ||
128 | { | ||
129 | u8 result = tas3004_treble_table[idx]; | ||
130 | |||
131 | if (idx >= 50) | ||
132 | result += tas3004_bass_diff_to_treble[idx-50]; | ||
133 | return result; | ||
134 | } | ||
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/snd-aoa-codec-tas.c index 2e39ff6ee349..16c0b6b0a805 100644 --- a/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/sound/aoa/codecs/snd-aoa-codec-tas.c | |||
@@ -72,22 +72,29 @@ MODULE_DESCRIPTION("tas codec driver for snd-aoa"); | |||
72 | 72 | ||
73 | #include "snd-aoa-codec-tas.h" | 73 | #include "snd-aoa-codec-tas.h" |
74 | #include "snd-aoa-codec-tas-gain-table.h" | 74 | #include "snd-aoa-codec-tas-gain-table.h" |
75 | #include "snd-aoa-codec-tas-basstreble.h" | ||
75 | #include "../aoa.h" | 76 | #include "../aoa.h" |
76 | #include "../soundbus/soundbus.h" | 77 | #include "../soundbus/soundbus.h" |
77 | 78 | ||
78 | |||
79 | #define PFX "snd-aoa-codec-tas: " | 79 | #define PFX "snd-aoa-codec-tas: " |
80 | 80 | ||
81 | |||
81 | struct tas { | 82 | struct tas { |
82 | struct aoa_codec codec; | 83 | struct aoa_codec codec; |
83 | struct i2c_client i2c; | 84 | struct i2c_client i2c; |
84 | u32 muted_l:1, muted_r:1, | 85 | u32 mute_l:1, mute_r:1 , |
85 | controls_created:1; | 86 | controls_created:1 , |
87 | drc_enabled:1, | ||
88 | hw_enabled:1; | ||
86 | u8 cached_volume_l, cached_volume_r; | 89 | u8 cached_volume_l, cached_volume_r; |
87 | u8 mixer_l[3], mixer_r[3]; | 90 | u8 mixer_l[3], mixer_r[3]; |
91 | u8 bass, treble; | ||
88 | u8 acr; | 92 | u8 acr; |
93 | int drc_range; | ||
89 | }; | 94 | }; |
90 | 95 | ||
96 | static int tas_reset_init(struct tas *tas); | ||
97 | |||
91 | static struct tas *codec_to_tas(struct aoa_codec *codec) | 98 | static struct tas *codec_to_tas(struct aoa_codec *codec) |
92 | { | 99 | { |
93 | return container_of(codec, struct tas, codec); | 100 | return container_of(codec, struct tas, codec); |
@@ -101,6 +108,44 @@ static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data) | |||
101 | return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data); | 108 | return i2c_smbus_write_i2c_block_data(&tas->i2c, reg, len, data); |
102 | } | 109 | } |
103 | 110 | ||
111 | static void tas3004_set_drc(struct tas *tas) | ||
112 | { | ||
113 | unsigned char val[6]; | ||
114 | |||
115 | if (tas->drc_enabled) | ||
116 | val[0] = 0x50; /* 3:1 above threshold */ | ||
117 | else | ||
118 | val[0] = 0x51; /* disabled */ | ||
119 | val[1] = 0x02; /* 1:1 below threshold */ | ||
120 | if (tas->drc_range > 0xef) | ||
121 | val[2] = 0xef; | ||
122 | else if (tas->drc_range < 0) | ||
123 | val[2] = 0x00; | ||
124 | else | ||
125 | val[2] = tas->drc_range; | ||
126 | val[3] = 0xb0; | ||
127 | val[4] = 0x60; | ||
128 | val[5] = 0xa0; | ||
129 | |||
130 | tas_write_reg(tas, TAS_REG_DRC, 6, val); | ||
131 | } | ||
132 | |||
133 | static void tas_set_treble(struct tas *tas) | ||
134 | { | ||
135 | u8 tmp; | ||
136 | |||
137 | tmp = tas3004_treble(tas->treble); | ||
138 | tas_write_reg(tas, TAS_REG_TREBLE, 1, &tmp); | ||
139 | } | ||
140 | |||
141 | static void tas_set_bass(struct tas *tas) | ||
142 | { | ||
143 | u8 tmp; | ||
144 | |||
145 | tmp = tas3004_bass(tas->bass); | ||
146 | tas_write_reg(tas, TAS_REG_BASS, 1, &tmp); | ||
147 | } | ||
148 | |||
104 | static void tas_set_volume(struct tas *tas) | 149 | static void tas_set_volume(struct tas *tas) |
105 | { | 150 | { |
106 | u8 block[6]; | 151 | u8 block[6]; |
@@ -113,8 +158,8 @@ static void tas_set_volume(struct tas *tas) | |||
113 | if (left > 177) left = 177; | 158 | if (left > 177) left = 177; |
114 | if (right > 177) right = 177; | 159 | if (right > 177) right = 177; |
115 | 160 | ||
116 | if (tas->muted_l) left = 0; | 161 | if (tas->mute_l) left = 0; |
117 | if (tas->muted_r) right = 0; | 162 | if (tas->mute_r) right = 0; |
118 | 163 | ||
119 | /* analysing the volume and mixer tables shows | 164 | /* analysing the volume and mixer tables shows |
120 | * that they are similar enough when we shift | 165 | * that they are similar enough when we shift |
@@ -202,7 +247,8 @@ static int tas_snd_vol_put(struct snd_kcontrol *kcontrol, | |||
202 | 247 | ||
203 | tas->cached_volume_l = ucontrol->value.integer.value[0]; | 248 | tas->cached_volume_l = ucontrol->value.integer.value[0]; |
204 | tas->cached_volume_r = ucontrol->value.integer.value[1]; | 249 | tas->cached_volume_r = ucontrol->value.integer.value[1]; |
205 | tas_set_volume(tas); | 250 | if (tas->hw_enabled) |
251 | tas_set_volume(tas); | ||
206 | return 1; | 252 | return 1; |
207 | } | 253 | } |
208 | 254 | ||
@@ -230,8 +276,8 @@ static int tas_snd_mute_get(struct snd_kcontrol *kcontrol, | |||
230 | { | 276 | { |
231 | struct tas *tas = snd_kcontrol_chip(kcontrol); | 277 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
232 | 278 | ||
233 | ucontrol->value.integer.value[0] = !tas->muted_l; | 279 | ucontrol->value.integer.value[0] = !tas->mute_l; |
234 | ucontrol->value.integer.value[1] = !tas->muted_r; | 280 | ucontrol->value.integer.value[1] = !tas->mute_r; |
235 | return 0; | 281 | return 0; |
236 | } | 282 | } |
237 | 283 | ||
@@ -240,13 +286,14 @@ static int tas_snd_mute_put(struct snd_kcontrol *kcontrol, | |||
240 | { | 286 | { |
241 | struct tas *tas = snd_kcontrol_chip(kcontrol); | 287 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
242 | 288 | ||
243 | if (tas->muted_l == !ucontrol->value.integer.value[0] | 289 | if (tas->mute_l == !ucontrol->value.integer.value[0] |
244 | && tas->muted_r == !ucontrol->value.integer.value[1]) | 290 | && tas->mute_r == !ucontrol->value.integer.value[1]) |
245 | return 0; | 291 | return 0; |
246 | 292 | ||
247 | tas->muted_l = !ucontrol->value.integer.value[0]; | 293 | tas->mute_l = !ucontrol->value.integer.value[0]; |
248 | tas->muted_r = !ucontrol->value.integer.value[1]; | 294 | tas->mute_r = !ucontrol->value.integer.value[1]; |
249 | tas_set_volume(tas); | 295 | if (tas->hw_enabled) |
296 | tas_set_volume(tas); | ||
250 | return 1; | 297 | return 1; |
251 | } | 298 | } |
252 | 299 | ||
@@ -294,7 +341,8 @@ static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol, | |||
294 | tas->mixer_l[idx] = ucontrol->value.integer.value[0]; | 341 | tas->mixer_l[idx] = ucontrol->value.integer.value[0]; |
295 | tas->mixer_r[idx] = ucontrol->value.integer.value[1]; | 342 | tas->mixer_r[idx] = ucontrol->value.integer.value[1]; |
296 | 343 | ||
297 | tas_set_mixer(tas); | 344 | if (tas->hw_enabled) |
345 | tas_set_mixer(tas); | ||
298 | return 1; | 346 | return 1; |
299 | } | 347 | } |
300 | 348 | ||
@@ -309,9 +357,93 @@ static struct snd_kcontrol_new n##_control = { \ | |||
309 | .private_value = idx, \ | 357 | .private_value = idx, \ |
310 | } | 358 | } |
311 | 359 | ||
312 | MIXER_CONTROL(pcm1, "PCM1", 0); | 360 | MIXER_CONTROL(pcm1, "PCM", 0); |
313 | MIXER_CONTROL(monitor, "Monitor", 2); | 361 | MIXER_CONTROL(monitor, "Monitor", 2); |
314 | 362 | ||
363 | static int tas_snd_drc_range_info(struct snd_kcontrol *kcontrol, | ||
364 | struct snd_ctl_elem_info *uinfo) | ||
365 | { | ||
366 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
367 | uinfo->count = 1; | ||
368 | uinfo->value.integer.min = 0; | ||
369 | uinfo->value.integer.max = TAS3004_DRC_MAX; | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol, | ||
374 | struct snd_ctl_elem_value *ucontrol) | ||
375 | { | ||
376 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
377 | |||
378 | ucontrol->value.integer.value[0] = tas->drc_range; | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol, | ||
383 | struct snd_ctl_elem_value *ucontrol) | ||
384 | { | ||
385 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
386 | |||
387 | if (tas->drc_range == ucontrol->value.integer.value[0]) | ||
388 | return 0; | ||
389 | |||
390 | tas->drc_range = ucontrol->value.integer.value[0]; | ||
391 | if (tas->hw_enabled) | ||
392 | tas3004_set_drc(tas); | ||
393 | return 1; | ||
394 | } | ||
395 | |||
396 | static struct snd_kcontrol_new drc_range_control = { | ||
397 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
398 | .name = "DRC Range", | ||
399 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
400 | .info = tas_snd_drc_range_info, | ||
401 | .get = tas_snd_drc_range_get, | ||
402 | .put = tas_snd_drc_range_put, | ||
403 | }; | ||
404 | |||
405 | static int tas_snd_drc_switch_info(struct snd_kcontrol *kcontrol, | ||
406 | struct snd_ctl_elem_info *uinfo) | ||
407 | { | ||
408 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
409 | uinfo->count = 1; | ||
410 | uinfo->value.integer.min = 0; | ||
411 | uinfo->value.integer.max = 1; | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol, | ||
416 | struct snd_ctl_elem_value *ucontrol) | ||
417 | { | ||
418 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
419 | |||
420 | ucontrol->value.integer.value[0] = tas->drc_enabled; | ||
421 | return 0; | ||
422 | } | ||
423 | |||
424 | static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol, | ||
425 | struct snd_ctl_elem_value *ucontrol) | ||
426 | { | ||
427 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
428 | |||
429 | if (tas->drc_enabled == ucontrol->value.integer.value[0]) | ||
430 | return 0; | ||
431 | |||
432 | tas->drc_enabled = ucontrol->value.integer.value[0]; | ||
433 | if (tas->hw_enabled) | ||
434 | tas3004_set_drc(tas); | ||
435 | return 1; | ||
436 | } | ||
437 | |||
438 | static struct snd_kcontrol_new drc_switch_control = { | ||
439 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
440 | .name = "DRC Range Switch", | ||
441 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
442 | .info = tas_snd_drc_switch_info, | ||
443 | .get = tas_snd_drc_switch_get, | ||
444 | .put = tas_snd_drc_switch_put, | ||
445 | }; | ||
446 | |||
315 | static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, | 447 | static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, |
316 | struct snd_ctl_elem_info *uinfo) | 448 | struct snd_ctl_elem_info *uinfo) |
317 | { | 449 | { |
@@ -346,7 +478,8 @@ static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol, | |||
346 | tas->acr |= TAS_ACR_INPUT_B; | 478 | tas->acr |= TAS_ACR_INPUT_B; |
347 | if (oldacr == tas->acr) | 479 | if (oldacr == tas->acr) |
348 | return 0; | 480 | return 0; |
349 | tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr); | 481 | if (tas->hw_enabled) |
482 | tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr); | ||
350 | return 1; | 483 | return 1; |
351 | } | 484 | } |
352 | 485 | ||
@@ -370,6 +503,89 @@ static struct snd_kcontrol_new capture_source_control = { | |||
370 | .put = tas_snd_capture_source_put, | 503 | .put = tas_snd_capture_source_put, |
371 | }; | 504 | }; |
372 | 505 | ||
506 | static int tas_snd_treble_info(struct snd_kcontrol *kcontrol, | ||
507 | struct snd_ctl_elem_info *uinfo) | ||
508 | { | ||
509 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
510 | uinfo->count = 1; | ||
511 | uinfo->value.integer.min = TAS3004_TREBLE_MIN; | ||
512 | uinfo->value.integer.max = TAS3004_TREBLE_MAX; | ||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static int tas_snd_treble_get(struct snd_kcontrol *kcontrol, | ||
517 | struct snd_ctl_elem_value *ucontrol) | ||
518 | { | ||
519 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
520 | |||
521 | ucontrol->value.integer.value[0] = tas->treble; | ||
522 | return 0; | ||
523 | } | ||
524 | |||
525 | static int tas_snd_treble_put(struct snd_kcontrol *kcontrol, | ||
526 | struct snd_ctl_elem_value *ucontrol) | ||
527 | { | ||
528 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
529 | |||
530 | if (tas->treble == ucontrol->value.integer.value[0]) | ||
531 | return 0; | ||
532 | |||
533 | tas->treble = ucontrol->value.integer.value[0]; | ||
534 | if (tas->hw_enabled) | ||
535 | tas_set_treble(tas); | ||
536 | return 1; | ||
537 | } | ||
538 | |||
539 | static struct snd_kcontrol_new treble_control = { | ||
540 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
541 | .name = "Treble", | ||
542 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
543 | .info = tas_snd_treble_info, | ||
544 | .get = tas_snd_treble_get, | ||
545 | .put = tas_snd_treble_put, | ||
546 | }; | ||
547 | |||
548 | static int tas_snd_bass_info(struct snd_kcontrol *kcontrol, | ||
549 | struct snd_ctl_elem_info *uinfo) | ||
550 | { | ||
551 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
552 | uinfo->count = 1; | ||
553 | uinfo->value.integer.min = TAS3004_BASS_MIN; | ||
554 | uinfo->value.integer.max = TAS3004_BASS_MAX; | ||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int tas_snd_bass_get(struct snd_kcontrol *kcontrol, | ||
559 | struct snd_ctl_elem_value *ucontrol) | ||
560 | { | ||
561 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
562 | |||
563 | ucontrol->value.integer.value[0] = tas->bass; | ||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static int tas_snd_bass_put(struct snd_kcontrol *kcontrol, | ||
568 | struct snd_ctl_elem_value *ucontrol) | ||
569 | { | ||
570 | struct tas *tas = snd_kcontrol_chip(kcontrol); | ||
571 | |||
572 | if (tas->bass == ucontrol->value.integer.value[0]) | ||
573 | return 0; | ||
574 | |||
575 | tas->bass = ucontrol->value.integer.value[0]; | ||
576 | if (tas->hw_enabled) | ||
577 | tas_set_bass(tas); | ||
578 | return 1; | ||
579 | } | ||
580 | |||
581 | static struct snd_kcontrol_new bass_control = { | ||
582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
583 | .name = "Bass", | ||
584 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
585 | .info = tas_snd_bass_info, | ||
586 | .get = tas_snd_bass_get, | ||
587 | .put = tas_snd_bass_put, | ||
588 | }; | ||
373 | 589 | ||
374 | static struct transfer_info tas_transfers[] = { | 590 | static struct transfer_info tas_transfers[] = { |
375 | { | 591 | { |
@@ -399,26 +615,67 @@ static int tas_usable(struct codec_info_item *cii, | |||
399 | static int tas_reset_init(struct tas *tas) | 615 | static int tas_reset_init(struct tas *tas) |
400 | { | 616 | { |
401 | u8 tmp; | 617 | u8 tmp; |
618 | |||
619 | tas->codec.gpio->methods->all_amps_off(tas->codec.gpio); | ||
620 | msleep(5); | ||
402 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); | 621 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); |
403 | msleep(1); | 622 | msleep(5); |
404 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1); | 623 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1); |
405 | msleep(1); | 624 | msleep(20); |
406 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); | 625 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); |
407 | msleep(1); | 626 | msleep(10); |
408 | 627 | tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio); | |
409 | tas->acr &= ~TAS_ACR_ANALOG_PDOWN; | ||
410 | tas->acr |= TAS_ACR_B_MONAUREAL | TAS_ACR_B_MON_SEL_RIGHT; | ||
411 | if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) | ||
412 | return -ENODEV; | ||
413 | 628 | ||
414 | tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT; | 629 | tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT; |
415 | if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp)) | 630 | if (tas_write_reg(tas, TAS_REG_MCS, 1, &tmp)) |
416 | return -ENODEV; | 631 | return -ENODEV; |
417 | 632 | ||
633 | tas->acr |= TAS_ACR_ANALOG_PDOWN | TAS_ACR_B_MONAUREAL | | ||
634 | TAS_ACR_B_MON_SEL_RIGHT; | ||
635 | if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) | ||
636 | return -ENODEV; | ||
637 | |||
418 | tmp = 0; | 638 | tmp = 0; |
419 | if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp)) | 639 | if (tas_write_reg(tas, TAS_REG_MCS2, 1, &tmp)) |
420 | return -ENODEV; | 640 | return -ENODEV; |
421 | 641 | ||
642 | tas3004_set_drc(tas); | ||
643 | |||
644 | /* Set treble & bass to 0dB */ | ||
645 | tas->treble = TAS3004_TREBLE_ZERO; | ||
646 | tas->bass = TAS3004_BASS_ZERO; | ||
647 | tas_set_treble(tas); | ||
648 | tas_set_bass(tas); | ||
649 | |||
650 | tas->acr &= ~TAS_ACR_ANALOG_PDOWN; | ||
651 | if (tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr)) | ||
652 | return -ENODEV; | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock) | ||
658 | { | ||
659 | struct tas *tas = cii->codec_data; | ||
660 | |||
661 | switch(clock) { | ||
662 | case CLOCK_SWITCH_PREPARE_SLAVE: | ||
663 | /* Clocks are going away, mute mute mute */ | ||
664 | tas->codec.gpio->methods->all_amps_off(tas->codec.gpio); | ||
665 | tas->hw_enabled = 0; | ||
666 | break; | ||
667 | case CLOCK_SWITCH_SLAVE: | ||
668 | /* Clocks are back, re-init the codec */ | ||
669 | tas_reset_init(tas); | ||
670 | tas_set_volume(tas); | ||
671 | tas_set_mixer(tas); | ||
672 | tas->hw_enabled = 1; | ||
673 | tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio); | ||
674 | break; | ||
675 | default: | ||
676 | /* doesn't happen as of now */ | ||
677 | return -EINVAL; | ||
678 | } | ||
422 | return 0; | 679 | return 0; |
423 | } | 680 | } |
424 | 681 | ||
@@ -427,6 +684,7 @@ static int tas_reset_init(struct tas *tas) | |||
427 | * our i2c device is suspended, and then take note of that! */ | 684 | * our i2c device is suspended, and then take note of that! */ |
428 | static int tas_suspend(struct tas *tas) | 685 | static int tas_suspend(struct tas *tas) |
429 | { | 686 | { |
687 | tas->hw_enabled = 0; | ||
430 | tas->acr |= TAS_ACR_ANALOG_PDOWN; | 688 | tas->acr |= TAS_ACR_ANALOG_PDOWN; |
431 | tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr); | 689 | tas_write_reg(tas, TAS_REG_ACR, 1, &tas->acr); |
432 | return 0; | 690 | return 0; |
@@ -438,6 +696,7 @@ static int tas_resume(struct tas *tas) | |||
438 | tas_reset_init(tas); | 696 | tas_reset_init(tas); |
439 | tas_set_volume(tas); | 697 | tas_set_volume(tas); |
440 | tas_set_mixer(tas); | 698 | tas_set_mixer(tas); |
699 | tas->hw_enabled = 1; | ||
441 | return 0; | 700 | return 0; |
442 | } | 701 | } |
443 | 702 | ||
@@ -463,6 +722,7 @@ static struct codec_info tas_codec_info = { | |||
463 | .bus_factor = 64, | 722 | .bus_factor = 64, |
464 | .owner = THIS_MODULE, | 723 | .owner = THIS_MODULE, |
465 | .usable = tas_usable, | 724 | .usable = tas_usable, |
725 | .switch_clock = tas_switch_clock, | ||
466 | #ifdef CONFIG_PM | 726 | #ifdef CONFIG_PM |
467 | .suspend = _tas_suspend, | 727 | .suspend = _tas_suspend, |
468 | .resume = _tas_resume, | 728 | .resume = _tas_resume, |
@@ -483,6 +743,7 @@ static int tas_init_codec(struct aoa_codec *codec) | |||
483 | printk(KERN_ERR PFX "tas failed to initialise\n"); | 743 | printk(KERN_ERR PFX "tas failed to initialise\n"); |
484 | return -ENXIO; | 744 | return -ENXIO; |
485 | } | 745 | } |
746 | tas->hw_enabled = 1; | ||
486 | 747 | ||
487 | if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev, | 748 | if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev, |
488 | aoa_get_card(), | 749 | aoa_get_card(), |
@@ -515,6 +776,22 @@ static int tas_init_codec(struct aoa_codec *codec) | |||
515 | if (err) | 776 | if (err) |
516 | goto error; | 777 | goto error; |
517 | 778 | ||
779 | err = aoa_snd_ctl_add(snd_ctl_new1(&drc_range_control, tas)); | ||
780 | if (err) | ||
781 | goto error; | ||
782 | |||
783 | err = aoa_snd_ctl_add(snd_ctl_new1(&drc_switch_control, tas)); | ||
784 | if (err) | ||
785 | goto error; | ||
786 | |||
787 | err = aoa_snd_ctl_add(snd_ctl_new1(&treble_control, tas)); | ||
788 | if (err) | ||
789 | goto error; | ||
790 | |||
791 | err = aoa_snd_ctl_add(snd_ctl_new1(&bass_control, tas)); | ||
792 | if (err) | ||
793 | goto error; | ||
794 | |||
518 | return 0; | 795 | return 0; |
519 | error: | 796 | error: |
520 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); | 797 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); |
@@ -548,6 +825,8 @@ static int tas_create(struct i2c_adapter *adapter, | |||
548 | tas->i2c.driver = &tas_driver; | 825 | tas->i2c.driver = &tas_driver; |
549 | tas->i2c.adapter = adapter; | 826 | tas->i2c.adapter = adapter; |
550 | tas->i2c.addr = addr; | 827 | tas->i2c.addr = addr; |
828 | /* seems that half is a saner default */ | ||
829 | tas->drc_range = TAS3004_DRC_MAX / 2; | ||
551 | strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1); | 830 | strlcpy(tas->i2c.name, "tas audio codec", I2C_NAME_SIZE-1); |
552 | 831 | ||
553 | if (i2c_attach_client(&tas->i2c)) { | 832 | if (i2c_attach_client(&tas->i2c)) { |
@@ -564,7 +843,9 @@ static int tas_create(struct i2c_adapter *adapter, | |||
564 | if (aoa_codec_register(&tas->codec)) { | 843 | if (aoa_codec_register(&tas->codec)) { |
565 | goto detach; | 844 | goto detach; |
566 | } | 845 | } |
567 | printk(KERN_DEBUG "snd-aoa-codec-tas: created and attached tas instance\n"); | 846 | printk(KERN_DEBUG |
847 | "snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n", | ||
848 | addr, node->full_name); | ||
568 | return 0; | 849 | return 0; |
569 | detach: | 850 | detach: |
570 | i2c_detach_client(&tas->i2c); | 851 | i2c_detach_client(&tas->i2c); |
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/snd-aoa-codec-tas.h index daf81f45d83a..ae177e3466e6 100644 --- a/sound/aoa/codecs/snd-aoa-codec-tas.h +++ b/sound/aoa/codecs/snd-aoa-codec-tas.h | |||
@@ -44,4 +44,12 @@ | |||
44 | #define TAS_REG_LEFT_BIQUAD6 0x10 | 44 | #define TAS_REG_LEFT_BIQUAD6 0x10 |
45 | #define TAS_REG_RIGHT_BIQUAD6 0x19 | 45 | #define TAS_REG_RIGHT_BIQUAD6 0x19 |
46 | 46 | ||
47 | #define TAS_REG_LEFT_LOUDNESS 0x21 | ||
48 | #define TAS_REG_RIGHT_LOUDNESS 0x22 | ||
49 | #define TAS_REG_LEFT_LOUDNESS_GAIN 0x23 | ||
50 | #define TAS_REG_RIGHT_LOUDNESS_GAIN 0x24 | ||
51 | |||
52 | #define TAS3001_DRC_MAX 0x5f | ||
53 | #define TAS3004_DRC_MAX 0xef | ||
54 | |||
47 | #endif /* __SND_AOA_CODECTASH */ | 55 | #endif /* __SND_AOA_CODECTASH */ |
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/snd-aoa-gpio-pmf.c index 0e9b9bb2a6de..3d57fd1aec4b 100644 --- a/sound/aoa/core/snd-aoa-gpio-pmf.c +++ b/sound/aoa/core/snd-aoa-gpio-pmf.c | |||
@@ -14,9 +14,13 @@ | |||
14 | static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\ | 14 | static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\ |
15 | { \ | 15 | { \ |
16 | struct pmf_args args = { .count = 1, .u[0].v = !on }; \ | 16 | struct pmf_args args = { .count = 1, .u[0].v = !on }; \ |
17 | \ | 17 | int rc; \ |
18 | \ | ||
18 | if (unlikely(!rt)) return; \ | 19 | if (unlikely(!rt)) return; \ |
19 | pmf_call_function(rt->node, #name "-mute", &args); \ | 20 | rc = pmf_call_function(rt->node, #name "-mute", &args); \ |
21 | if (rc) \ | ||
22 | printk(KERN_WARNING "pmf_gpio_set_" #name \ | ||
23 | " failed, rc: %d\n", rc); \ | ||
20 | rt->implementation_private &= ~(1<<bit); \ | 24 | rt->implementation_private &= ~(1<<bit); \ |
21 | rt->implementation_private |= (!!on << bit); \ | 25 | rt->implementation_private |= (!!on << bit); \ |
22 | } \ | 26 | } \ |
@@ -33,9 +37,13 @@ PMF_GPIO(lineout, 2); | |||
33 | static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on) | 37 | static void pmf_gpio_set_hw_reset(struct gpio_runtime *rt, int on) |
34 | { | 38 | { |
35 | struct pmf_args args = { .count = 1, .u[0].v = !!on }; | 39 | struct pmf_args args = { .count = 1, .u[0].v = !!on }; |
40 | int rc; | ||
36 | 41 | ||
37 | if (unlikely(!rt)) return; | 42 | if (unlikely(!rt)) return; |
38 | pmf_call_function(rt->node, "hw-reset", &args); | 43 | rc = pmf_call_function(rt->node, "hw-reset", &args); |
44 | if (rc) | ||
45 | printk(KERN_WARNING "pmf_gpio_set_hw_reset" | ||
46 | " failed, rc: %d\n", rc); | ||
39 | } | 47 | } |
40 | 48 | ||
41 | static void pmf_gpio_all_amps_off(struct gpio_runtime *rt) | 49 | static void pmf_gpio_all_amps_off(struct gpio_runtime *rt) |
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/snd-aoa-fabric-layout.c index cbc8a3b5cea4..172eb95476c0 100644 --- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c +++ b/sound/aoa/fabrics/snd-aoa-fabric-layout.c | |||
@@ -77,24 +77,39 @@ struct layout { | |||
77 | int pcmid; | 77 | int pcmid; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | MODULE_ALIAS("sound-layout-36"); | ||
80 | MODULE_ALIAS("sound-layout-41"); | 81 | MODULE_ALIAS("sound-layout-41"); |
81 | MODULE_ALIAS("sound-layout-45"); | 82 | MODULE_ALIAS("sound-layout-45"); |
83 | MODULE_ALIAS("sound-layout-47"); | ||
84 | MODULE_ALIAS("sound-layout-48"); | ||
85 | MODULE_ALIAS("sound-layout-49"); | ||
86 | MODULE_ALIAS("sound-layout-50"); | ||
82 | MODULE_ALIAS("sound-layout-51"); | 87 | MODULE_ALIAS("sound-layout-51"); |
88 | MODULE_ALIAS("sound-layout-56"); | ||
89 | MODULE_ALIAS("sound-layout-57"); | ||
83 | MODULE_ALIAS("sound-layout-58"); | 90 | MODULE_ALIAS("sound-layout-58"); |
84 | MODULE_ALIAS("sound-layout-60"); | 91 | MODULE_ALIAS("sound-layout-60"); |
85 | MODULE_ALIAS("sound-layout-61"); | 92 | MODULE_ALIAS("sound-layout-61"); |
93 | MODULE_ALIAS("sound-layout-62"); | ||
86 | MODULE_ALIAS("sound-layout-64"); | 94 | MODULE_ALIAS("sound-layout-64"); |
87 | MODULE_ALIAS("sound-layout-65"); | 95 | MODULE_ALIAS("sound-layout-65"); |
96 | MODULE_ALIAS("sound-layout-66"); | ||
97 | MODULE_ALIAS("sound-layout-67"); | ||
88 | MODULE_ALIAS("sound-layout-68"); | 98 | MODULE_ALIAS("sound-layout-68"); |
89 | MODULE_ALIAS("sound-layout-69"); | 99 | MODULE_ALIAS("sound-layout-69"); |
90 | MODULE_ALIAS("sound-layout-70"); | 100 | MODULE_ALIAS("sound-layout-70"); |
91 | MODULE_ALIAS("sound-layout-72"); | 101 | MODULE_ALIAS("sound-layout-72"); |
102 | MODULE_ALIAS("sound-layout-76"); | ||
92 | MODULE_ALIAS("sound-layout-80"); | 103 | MODULE_ALIAS("sound-layout-80"); |
93 | MODULE_ALIAS("sound-layout-82"); | 104 | MODULE_ALIAS("sound-layout-82"); |
94 | MODULE_ALIAS("sound-layout-84"); | 105 | MODULE_ALIAS("sound-layout-84"); |
95 | MODULE_ALIAS("sound-layout-86"); | 106 | MODULE_ALIAS("sound-layout-86"); |
107 | MODULE_ALIAS("sound-layout-90"); | ||
96 | MODULE_ALIAS("sound-layout-92"); | 108 | MODULE_ALIAS("sound-layout-92"); |
109 | MODULE_ALIAS("sound-layout-94"); | ||
97 | MODULE_ALIAS("sound-layout-96"); | 110 | MODULE_ALIAS("sound-layout-96"); |
111 | MODULE_ALIAS("sound-layout-98"); | ||
112 | MODULE_ALIAS("sound-layout-100"); | ||
98 | 113 | ||
99 | /* onyx with all but microphone connected */ | 114 | /* onyx with all but microphone connected */ |
100 | static struct codec_connection onyx_connections_nomic[] = { | 115 | static struct codec_connection onyx_connections_nomic[] = { |
@@ -950,11 +965,12 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) | |||
950 | layout_id = (unsigned int *) get_property(sound, "layout-id", NULL); | 965 | layout_id = (unsigned int *) get_property(sound, "layout-id", NULL); |
951 | if (!layout_id) | 966 | if (!layout_id) |
952 | goto outnodev; | 967 | goto outnodev; |
953 | printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d ", *layout_id); | 968 | printk(KERN_INFO "snd-aoa-fabric-layout: found bus with layout %d\n", |
969 | *layout_id); | ||
954 | 970 | ||
955 | layout = find_layout_by_id(*layout_id); | 971 | layout = find_layout_by_id(*layout_id); |
956 | if (!layout) { | 972 | if (!layout) { |
957 | printk("(no idea how to handle)\n"); | 973 | printk(KERN_ERR "snd-aoa-fabric-layout: unknown layout\n"); |
958 | goto outnodev; | 974 | goto outnodev; |
959 | } | 975 | } |
960 | 976 | ||
@@ -972,15 +988,17 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) | |||
972 | case 51: /* PowerBook5,4 */ | 988 | case 51: /* PowerBook5,4 */ |
973 | case 58: /* Mac Mini */ | 989 | case 58: /* Mac Mini */ |
974 | ldev->gpio.methods = ftr_gpio_methods; | 990 | ldev->gpio.methods = ftr_gpio_methods; |
991 | printk(KERN_DEBUG | ||
992 | "snd-aoa-fabric-layout: Using direct GPIOs\n"); | ||
975 | break; | 993 | break; |
976 | default: | 994 | default: |
977 | ldev->gpio.methods = pmf_gpio_methods; | 995 | ldev->gpio.methods = pmf_gpio_methods; |
996 | printk(KERN_DEBUG | ||
997 | "snd-aoa-fabric-layout: Using PMF GPIOs\n"); | ||
978 | } | 998 | } |
979 | ldev->selfptr_headphone.ptr = ldev; | 999 | ldev->selfptr_headphone.ptr = ldev; |
980 | ldev->selfptr_lineout.ptr = ldev; | 1000 | ldev->selfptr_lineout.ptr = ldev; |
981 | sdev->ofdev.dev.driver_data = ldev; | 1001 | sdev->ofdev.dev.driver_data = ldev; |
982 | |||
983 | printk("(using)\n"); | ||
984 | list_add(&ldev->list, &layouts_list); | 1002 | list_add(&ldev->list, &layouts_list); |
985 | layouts_list_items++; | 1003 | layouts_list_items++; |
986 | 1004 | ||
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c index abe84a76c835..47b3e3768df0 100644 --- a/sound/aoa/soundbus/core.c +++ b/sound/aoa/soundbus/core.c | |||
@@ -194,16 +194,6 @@ static struct bus_type soundbus_bus_type = { | |||
194 | .dev_attrs = soundbus_dev_attrs, | 194 | .dev_attrs = soundbus_dev_attrs, |
195 | }; | 195 | }; |
196 | 196 | ||
197 | static int __init soundbus_init(void) | ||
198 | { | ||
199 | return bus_register(&soundbus_bus_type); | ||
200 | } | ||
201 | |||
202 | static void __exit soundbus_exit(void) | ||
203 | { | ||
204 | bus_unregister(&soundbus_bus_type); | ||
205 | } | ||
206 | |||
207 | int soundbus_add_one(struct soundbus_dev *dev) | 197 | int soundbus_add_one(struct soundbus_dev *dev) |
208 | { | 198 | { |
209 | static int devcount; | 199 | static int devcount; |
@@ -246,5 +236,15 @@ void soundbus_unregister_driver(struct soundbus_driver *drv) | |||
246 | } | 236 | } |
247 | EXPORT_SYMBOL_GPL(soundbus_unregister_driver); | 237 | EXPORT_SYMBOL_GPL(soundbus_unregister_driver); |
248 | 238 | ||
249 | module_init(soundbus_init); | 239 | static int __init soundbus_init(void) |
240 | { | ||
241 | return bus_register(&soundbus_bus_type); | ||
242 | } | ||
243 | |||
244 | static void __exit soundbus_exit(void) | ||
245 | { | ||
246 | bus_unregister(&soundbus_bus_type); | ||
247 | } | ||
248 | |||
249 | subsys_initcall(soundbus_init); | ||
250 | module_exit(soundbus_exit); | 250 | module_exit(soundbus_exit); |
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/i2sbus-control.c index f50407952d3c..87beb4ad4d63 100644 --- a/sound/aoa/soundbus/i2sbus/i2sbus-control.c +++ b/sound/aoa/soundbus/i2sbus/i2sbus-control.c | |||
@@ -6,12 +6,16 @@ | |||
6 | * GPL v2, can be found in COPYING. | 6 | * GPL v2, can be found in COPYING. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <asm/io.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | |||
12 | #include <asm/io.h> | ||
11 | #include <asm/prom.h> | 13 | #include <asm/prom.h> |
12 | #include <asm/macio.h> | 14 | #include <asm/macio.h> |
13 | #include <asm/pmac_feature.h> | 15 | #include <asm/pmac_feature.h> |
14 | #include <asm/pmac_pfunc.h> | 16 | #include <asm/pmac_pfunc.h> |
17 | #include <asm/keylargo.h> | ||
18 | |||
15 | #include "i2sbus.h" | 19 | #include "i2sbus.h" |
16 | 20 | ||
17 | int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c) | 21 | int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c) |
@@ -22,26 +26,12 @@ int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c) | |||
22 | 26 | ||
23 | INIT_LIST_HEAD(&(*c)->list); | 27 | INIT_LIST_HEAD(&(*c)->list); |
24 | 28 | ||
25 | if (of_address_to_resource(dev->ofdev.node, 0, &(*c)->rsrc)) | 29 | (*c)->macio = dev->bus->chip; |
26 | goto err; | ||
27 | /* we really should be using feature calls instead of mapping | ||
28 | * these registers. It's safe for now since no one else is | ||
29 | * touching them... */ | ||
30 | (*c)->controlregs = ioremap((*c)->rsrc.start, | ||
31 | sizeof(struct i2s_control_regs)); | ||
32 | if (!(*c)->controlregs) | ||
33 | goto err; | ||
34 | |||
35 | return 0; | 30 | return 0; |
36 | err: | ||
37 | kfree(*c); | ||
38 | *c = NULL; | ||
39 | return -ENODEV; | ||
40 | } | 31 | } |
41 | 32 | ||
42 | void i2sbus_control_destroy(struct i2sbus_control *c) | 33 | void i2sbus_control_destroy(struct i2sbus_control *c) |
43 | { | 34 | { |
44 | iounmap(c->controlregs); | ||
45 | kfree(c); | 35 | kfree(c); |
46 | } | 36 | } |
47 | 37 | ||
@@ -93,19 +83,22 @@ int i2sbus_control_enable(struct i2sbus_control *c, | |||
93 | struct i2sbus_dev *i2sdev) | 83 | struct i2sbus_dev *i2sdev) |
94 | { | 84 | { |
95 | struct pmf_args args = { .count = 0 }; | 85 | struct pmf_args args = { .count = 0 }; |
96 | int cc; | 86 | struct macio_chip *macio = c->macio; |
97 | 87 | ||
98 | if (i2sdev->enable) | 88 | if (i2sdev->enable) |
99 | return pmf_call_one(i2sdev->enable, &args); | 89 | return pmf_call_one(i2sdev->enable, &args); |
100 | 90 | ||
91 | if (macio == NULL || macio->base == NULL) | ||
92 | return -ENODEV; | ||
93 | |||
101 | switch (i2sdev->bus_number) { | 94 | switch (i2sdev->bus_number) { |
102 | case 0: | 95 | case 0: |
103 | cc = in_le32(&c->controlregs->cell_control); | 96 | /* these need to be locked or done through |
104 | out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_0_ENABLE); | 97 | * newly created feature calls! */ |
98 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE); | ||
105 | break; | 99 | break; |
106 | case 1: | 100 | case 1: |
107 | cc = in_le32(&c->controlregs->cell_control); | 101 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_ENABLE); |
108 | out_le32(&c->controlregs->cell_control, cc | CTRL_CLOCK_INTF_1_ENABLE); | ||
109 | break; | 102 | break; |
110 | default: | 103 | default: |
111 | return -ENODEV; | 104 | return -ENODEV; |
@@ -118,7 +111,7 @@ int i2sbus_control_cell(struct i2sbus_control *c, | |||
118 | int enable) | 111 | int enable) |
119 | { | 112 | { |
120 | struct pmf_args args = { .count = 0 }; | 113 | struct pmf_args args = { .count = 0 }; |
121 | int cc; | 114 | struct macio_chip *macio = c->macio; |
122 | 115 | ||
123 | switch (enable) { | 116 | switch (enable) { |
124 | case 0: | 117 | case 0: |
@@ -133,18 +126,22 @@ int i2sbus_control_cell(struct i2sbus_control *c, | |||
133 | printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n"); | 126 | printk(KERN_ERR "i2sbus: INVALID CELL ENABLE VALUE\n"); |
134 | return -ENODEV; | 127 | return -ENODEV; |
135 | } | 128 | } |
129 | |||
130 | if (macio == NULL || macio->base == NULL) | ||
131 | return -ENODEV; | ||
132 | |||
136 | switch (i2sdev->bus_number) { | 133 | switch (i2sdev->bus_number) { |
137 | case 0: | 134 | case 0: |
138 | cc = in_le32(&c->controlregs->cell_control); | 135 | if (enable) |
139 | cc &= ~CTRL_CLOCK_CELL_0_ENABLE; | 136 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE); |
140 | cc |= enable * CTRL_CLOCK_CELL_0_ENABLE; | 137 | else |
141 | out_le32(&c->controlregs->cell_control, cc); | 138 | MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE); |
142 | break; | 139 | break; |
143 | case 1: | 140 | case 1: |
144 | cc = in_le32(&c->controlregs->cell_control); | 141 | if (enable) |
145 | cc &= ~CTRL_CLOCK_CELL_1_ENABLE; | 142 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE); |
146 | cc |= enable * CTRL_CLOCK_CELL_1_ENABLE; | 143 | else |
147 | out_le32(&c->controlregs->cell_control, cc); | 144 | MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CELL_ENABLE); |
148 | break; | 145 | break; |
149 | default: | 146 | default: |
150 | return -ENODEV; | 147 | return -ENODEV; |
@@ -157,7 +154,7 @@ int i2sbus_control_clock(struct i2sbus_control *c, | |||
157 | int enable) | 154 | int enable) |
158 | { | 155 | { |
159 | struct pmf_args args = { .count = 0 }; | 156 | struct pmf_args args = { .count = 0 }; |
160 | int cc; | 157 | struct macio_chip *macio = c->macio; |
161 | 158 | ||
162 | switch (enable) { | 159 | switch (enable) { |
163 | case 0: | 160 | case 0: |
@@ -172,18 +169,22 @@ int i2sbus_control_clock(struct i2sbus_control *c, | |||
172 | printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n"); | 169 | printk(KERN_ERR "i2sbus: INVALID CLOCK ENABLE VALUE\n"); |
173 | return -ENODEV; | 170 | return -ENODEV; |
174 | } | 171 | } |
172 | |||
173 | if (macio == NULL || macio->base == NULL) | ||
174 | return -ENODEV; | ||
175 | |||
175 | switch (i2sdev->bus_number) { | 176 | switch (i2sdev->bus_number) { |
176 | case 0: | 177 | case 0: |
177 | cc = in_le32(&c->controlregs->cell_control); | 178 | if (enable) |
178 | cc &= ~CTRL_CLOCK_CLOCK_0_ENABLE; | 179 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT); |
179 | cc |= enable * CTRL_CLOCK_CLOCK_0_ENABLE; | 180 | else |
180 | out_le32(&c->controlregs->cell_control, cc); | 181 | MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT); |
181 | break; | 182 | break; |
182 | case 1: | 183 | case 1: |
183 | cc = in_le32(&c->controlregs->cell_control); | 184 | if (enable) |
184 | cc &= ~CTRL_CLOCK_CLOCK_1_ENABLE; | 185 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT); |
185 | cc |= enable * CTRL_CLOCK_CLOCK_1_ENABLE; | 186 | else |
186 | out_le32(&c->controlregs->cell_control, cc); | 187 | MACIO_BIC(KEYLARGO_FCR1, KL1_I2S1_CLK_ENABLE_BIT); |
187 | break; | 188 | break; |
188 | default: | 189 | default: |
189 | return -ENODEV; | 190 | return -ENODEV; |
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.h b/sound/aoa/soundbus/i2sbus/i2sbus-control.h deleted file mode 100644 index bb05550f730b..000000000000 --- a/sound/aoa/soundbus/i2sbus/i2sbus-control.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * i2sbus driver -- bus register definitions | ||
3 | * | ||
4 | * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * GPL v2, can be found in COPYING. | ||
7 | */ | ||
8 | #ifndef __I2SBUS_CONTROLREGS_H | ||
9 | #define __I2SBUS_CONTROLREGS_H | ||
10 | |||
11 | /* i2s control registers, at least what we know about them */ | ||
12 | |||
13 | #define __PAD(m,n) u8 __pad##m[n] | ||
14 | #define _PAD(line, n) __PAD(line, n) | ||
15 | #define PAD(n) _PAD(__LINE__, (n)) | ||
16 | struct i2s_control_regs { | ||
17 | PAD(0x38); | ||
18 | __le32 fcr0; /* 0x38 (unknown) */ | ||
19 | __le32 cell_control; /* 0x3c (fcr1) */ | ||
20 | __le32 fcr2; /* 0x40 (unknown) */ | ||
21 | __le32 fcr3; /* 0x44 (fcr3) */ | ||
22 | __le32 clock_control; /* 0x48 (unknown) */ | ||
23 | PAD(4); | ||
24 | /* total size: 0x50 bytes */ | ||
25 | } __attribute__((__packed__)); | ||
26 | |||
27 | #define CTRL_CLOCK_CELL_0_ENABLE (1<<10) | ||
28 | #define CTRL_CLOCK_CLOCK_0_ENABLE (1<<12) | ||
29 | #define CTRL_CLOCK_SWRESET_0 (1<<11) | ||
30 | #define CTRL_CLOCK_INTF_0_ENABLE (1<<13) | ||
31 | |||
32 | #define CTRL_CLOCK_CELL_1_ENABLE (1<<17) | ||
33 | #define CTRL_CLOCK_CLOCK_1_ENABLE (1<<18) | ||
34 | #define CTRL_CLOCK_SWRESET_1 (1<<19) | ||
35 | #define CTRL_CLOCK_INTF_1_ENABLE (1<<20) | ||
36 | |||
37 | #endif /* __I2SBUS_CONTROLREGS_H */ | ||
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/i2sbus-core.c index 01c0724335a3..23190aa6bc7b 100644 --- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/sound/aoa/soundbus/i2sbus/i2sbus-core.c | |||
@@ -7,13 +7,16 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <asm/macio.h> | ||
11 | #include <asm/dbdma.h> | ||
12 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
13 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/dma-mapping.h> | ||
13 | |||
14 | #include <sound/driver.h> | 14 | #include <sound/driver.h> |
15 | #include <sound/core.h> | 15 | #include <sound/core.h> |
16 | #include <linux/dma-mapping.h> | 16 | |
17 | #include <asm/macio.h> | ||
18 | #include <asm/dbdma.h> | ||
19 | |||
17 | #include "../soundbus.h" | 20 | #include "../soundbus.h" |
18 | #include "i2sbus.h" | 21 | #include "i2sbus.h" |
19 | 22 | ||
@@ -24,6 +27,11 @@ MODULE_DESCRIPTION("Apple Soundbus: I2S support"); | |||
24 | * string that macio puts into the relevant device */ | 27 | * string that macio puts into the relevant device */ |
25 | MODULE_ALIAS("of:Ni2sTi2sC"); | 28 | MODULE_ALIAS("of:Ni2sTi2sC"); |
26 | 29 | ||
30 | static int force; | ||
31 | module_param(force, int, 0444); | ||
32 | MODULE_PARM_DESC(force, "Force loading i2sbus even when" | ||
33 | " no layout-id property is present"); | ||
34 | |||
27 | static struct of_device_id i2sbus_match[] = { | 35 | static struct of_device_id i2sbus_match[] = { |
28 | { .name = "i2s" }, | 36 | { .name = "i2s" }, |
29 | { } | 37 | { } |
@@ -73,12 +81,12 @@ static void i2sbus_release_dev(struct device *dev) | |||
73 | if (i2sdev->intfregs) iounmap(i2sdev->intfregs); | 81 | if (i2sdev->intfregs) iounmap(i2sdev->intfregs); |
74 | if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); | 82 | if (i2sdev->out.dbdma) iounmap(i2sdev->out.dbdma); |
75 | if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); | 83 | if (i2sdev->in.dbdma) iounmap(i2sdev->in.dbdma); |
76 | for (i=0;i<3;i++) | 84 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) |
77 | if (i2sdev->allocated_resource[i]) | 85 | if (i2sdev->allocated_resource[i]) |
78 | release_and_free_resource(i2sdev->allocated_resource[i]); | 86 | release_and_free_resource(i2sdev->allocated_resource[i]); |
79 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); | 87 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); |
80 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); | 88 | free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); |
81 | for (i=0;i<3;i++) | 89 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) |
82 | free_irq(i2sdev->interrupts[i], i2sdev); | 90 | free_irq(i2sdev->interrupts[i], i2sdev); |
83 | i2sbus_control_remove_dev(i2sdev->control, i2sdev); | 91 | i2sbus_control_remove_dev(i2sdev->control, i2sdev); |
84 | mutex_destroy(&i2sdev->lock); | 92 | mutex_destroy(&i2sdev->lock); |
@@ -101,10 +109,49 @@ static irqreturn_t i2sbus_bus_intr(int irq, void *devid, struct pt_regs *regs) | |||
101 | return IRQ_HANDLED; | 109 | return IRQ_HANDLED; |
102 | } | 110 | } |
103 | 111 | ||
104 | static int force; | 112 | |
105 | module_param(force, int, 0444); | 113 | /* |
106 | MODULE_PARM_DESC(force, "Force loading i2sbus even when" | 114 | * XXX FIXME: We test the layout_id's here to get the proper way of |
107 | " no layout-id property is present"); | 115 | * mapping in various registers, thanks to bugs in Apple device-trees. |
116 | * We could instead key off the machine model and the name of the i2s | ||
117 | * node (i2s-a). This we'll do when we move it all to macio_asic.c | ||
118 | * and have that export items for each sub-node too. | ||
119 | */ | ||
120 | static int i2sbus_get_and_fixup_rsrc(struct device_node *np, int index, | ||
121 | int layout, struct resource *res) | ||
122 | { | ||
123 | struct device_node *parent; | ||
124 | int pindex, rc = -ENXIO; | ||
125 | u32 *reg; | ||
126 | |||
127 | /* Machines with layout 76 and 36 (K2 based) have a weird device | ||
128 | * tree what we need to special case. | ||
129 | * Normal machines just fetch the resource from the i2s-X node. | ||
130 | * Darwin further divides normal machines into old and new layouts | ||
131 | * with a subtely different code path but that doesn't seem necessary | ||
132 | * in practice, they just bloated it. In addition, even on our K2 | ||
133 | * case the i2s-modem node, if we ever want to handle it, uses the | ||
134 | * normal layout | ||
135 | */ | ||
136 | if (layout != 76 && layout != 36) | ||
137 | return of_address_to_resource(np, index, res); | ||
138 | |||
139 | parent = of_get_parent(np); | ||
140 | pindex = (index == aoa_resource_i2smmio) ? 0 : 1; | ||
141 | rc = of_address_to_resource(parent, pindex, res); | ||
142 | if (rc) | ||
143 | goto bail; | ||
144 | reg = (u32 *)get_property(np, "reg", NULL); | ||
145 | if (reg == NULL) { | ||
146 | rc = -ENXIO; | ||
147 | goto bail; | ||
148 | } | ||
149 | res->start += reg[index * 2]; | ||
150 | res->end = res->start + reg[index * 2 + 1] - 1; | ||
151 | bail: | ||
152 | of_node_put(parent); | ||
153 | return rc; | ||
154 | } | ||
108 | 155 | ||
109 | /* FIXME: look at device node refcounting */ | 156 | /* FIXME: look at device node refcounting */ |
110 | static int i2sbus_add_dev(struct macio_dev *macio, | 157 | static int i2sbus_add_dev(struct macio_dev *macio, |
@@ -113,7 +160,8 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
113 | { | 160 | { |
114 | struct i2sbus_dev *dev; | 161 | struct i2sbus_dev *dev; |
115 | struct device_node *child = NULL, *sound = NULL; | 162 | struct device_node *child = NULL, *sound = NULL; |
116 | int i; | 163 | struct resource *r; |
164 | int i, layout = 0, rlen; | ||
117 | static const char *rnames[] = { "i2sbus: %s (control)", | 165 | static const char *rnames[] = { "i2sbus: %s (control)", |
118 | "i2sbus: %s (tx)", | 166 | "i2sbus: %s (tx)", |
119 | "i2sbus: %s (rx)" }; | 167 | "i2sbus: %s (rx)" }; |
@@ -129,9 +177,6 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
129 | if (strncmp(np->name, "i2s-", 4)) | 177 | if (strncmp(np->name, "i2s-", 4)) |
130 | return 0; | 178 | return 0; |
131 | 179 | ||
132 | if (macio_irq_count(macio) != 3) | ||
133 | return 0; | ||
134 | |||
135 | dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL); | 180 | dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL); |
136 | if (!dev) | 181 | if (!dev) |
137 | return 0; | 182 | return 0; |
@@ -147,8 +192,9 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
147 | u32 *layout_id; | 192 | u32 *layout_id; |
148 | layout_id = (u32*) get_property(sound, "layout-id", NULL); | 193 | layout_id = (u32*) get_property(sound, "layout-id", NULL); |
149 | if (layout_id) { | 194 | if (layout_id) { |
195 | layout = *layout_id; | ||
150 | snprintf(dev->sound.modalias, 32, | 196 | snprintf(dev->sound.modalias, 32, |
151 | "sound-layout-%d", *layout_id); | 197 | "sound-layout-%d", layout); |
152 | force = 1; | 198 | force = 1; |
153 | } | 199 | } |
154 | } | 200 | } |
@@ -178,23 +224,32 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
178 | dev->bus_number = np->name[4] - 'a'; | 224 | dev->bus_number = np->name[4] - 'a'; |
179 | INIT_LIST_HEAD(&dev->sound.codec_list); | 225 | INIT_LIST_HEAD(&dev->sound.codec_list); |
180 | 226 | ||
181 | for (i=0;i<3;i++) { | 227 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { |
182 | dev->interrupts[i] = -1; | 228 | dev->interrupts[i] = -1; |
183 | snprintf(dev->rnames[i], sizeof(dev->rnames[i]), rnames[i], np->name); | 229 | snprintf(dev->rnames[i], sizeof(dev->rnames[i]), |
230 | rnames[i], np->name); | ||
184 | } | 231 | } |
185 | for (i=0;i<3;i++) { | 232 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { |
186 | if (request_irq(macio_irq(macio, i), ints[i], 0, | 233 | int irq = irq_of_parse_and_map(np, i); |
187 | dev->rnames[i], dev)) | 234 | if (request_irq(irq, ints[i], 0, dev->rnames[i], dev)) |
188 | goto err; | 235 | goto err; |
189 | dev->interrupts[i] = macio_irq(macio, i); | 236 | dev->interrupts[i] = irq; |
190 | } | 237 | } |
191 | 238 | ||
192 | for (i=0;i<3;i++) { | 239 | |
193 | if (of_address_to_resource(np, i, &dev->resources[i])) | 240 | /* Resource handling is problematic as some device-trees contain |
241 | * useless crap (ugh ugh ugh). We work around that here by calling | ||
242 | * specific functions for calculating the appropriate resources. | ||
243 | * | ||
244 | * This will all be moved to macio_asic.c at one point | ||
245 | */ | ||
246 | for (i = aoa_resource_i2smmio; i <= aoa_resource_rxdbdma; i++) { | ||
247 | if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i])) | ||
194 | goto err; | 248 | goto err; |
195 | /* if only we could use our resource dev->resources[i]... | 249 | /* If only we could use our resource dev->resources[i]... |
196 | * but request_resource doesn't know about parents and | 250 | * but request_resource doesn't know about parents and |
197 | * contained resources... */ | 251 | * contained resources... |
252 | */ | ||
198 | dev->allocated_resource[i] = | 253 | dev->allocated_resource[i] = |
199 | request_mem_region(dev->resources[i].start, | 254 | request_mem_region(dev->resources[i].start, |
200 | dev->resources[i].end - | 255 | dev->resources[i].end - |
@@ -205,13 +260,25 @@ static int i2sbus_add_dev(struct macio_dev *macio, | |||
205 | goto err; | 260 | goto err; |
206 | } | 261 | } |
207 | } | 262 | } |
208 | /* should do sanity checking here about length of them */ | 263 | |
209 | dev->intfregs = ioremap(dev->resources[0].start, | 264 | r = &dev->resources[aoa_resource_i2smmio]; |
210 | dev->resources[0].end-dev->resources[0].start+1); | 265 | rlen = r->end - r->start + 1; |
211 | dev->out.dbdma = ioremap(dev->resources[1].start, | 266 | if (rlen < sizeof(struct i2s_interface_regs)) |
212 | dev->resources[1].end-dev->resources[1].start+1); | 267 | goto err; |
213 | dev->in.dbdma = ioremap(dev->resources[2].start, | 268 | dev->intfregs = ioremap(r->start, rlen); |
214 | dev->resources[2].end-dev->resources[2].start+1); | 269 | |
270 | r = &dev->resources[aoa_resource_txdbdma]; | ||
271 | rlen = r->end - r->start + 1; | ||
272 | if (rlen < sizeof(struct dbdma_regs)) | ||
273 | goto err; | ||
274 | dev->out.dbdma = ioremap(r->start, rlen); | ||
275 | |||
276 | r = &dev->resources[aoa_resource_rxdbdma]; | ||
277 | rlen = r->end - r->start + 1; | ||
278 | if (rlen < sizeof(struct dbdma_regs)) | ||
279 | goto err; | ||
280 | dev->in.dbdma = ioremap(r->start, rlen); | ||
281 | |||
215 | if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma) | 282 | if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma) |
216 | goto err; | 283 | goto err; |
217 | 284 | ||
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h index cfa5162e3b0f..0c69d209be50 100644 --- a/sound/aoa/soundbus/i2sbus/i2sbus.h +++ b/sound/aoa/soundbus/i2sbus/i2sbus.h | |||
@@ -7,20 +7,22 @@ | |||
7 | */ | 7 | */ |
8 | #ifndef __I2SBUS_H | 8 | #ifndef __I2SBUS_H |
9 | #define __I2SBUS_H | 9 | #define __I2SBUS_H |
10 | #include <asm/dbdma.h> | ||
11 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
12 | #include <sound/pcm.h> | ||
13 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
14 | #include <linux/mutex.h> | 12 | #include <linux/mutex.h> |
13 | |||
14 | #include <sound/pcm.h> | ||
15 | |||
15 | #include <asm/prom.h> | 16 | #include <asm/prom.h> |
17 | #include <asm/pmac_feature.h> | ||
18 | #include <asm/dbdma.h> | ||
19 | |||
16 | #include "i2sbus-interface.h" | 20 | #include "i2sbus-interface.h" |
17 | #include "i2sbus-control.h" | ||
18 | #include "../soundbus.h" | 21 | #include "../soundbus.h" |
19 | 22 | ||
20 | struct i2sbus_control { | 23 | struct i2sbus_control { |
21 | volatile struct i2s_control_regs __iomem *controlregs; | ||
22 | struct resource rsrc; | ||
23 | struct list_head list; | 24 | struct list_head list; |
25 | struct macio_chip *macio; | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | #define MAX_DBDMA_COMMANDS 32 | 28 | #define MAX_DBDMA_COMMANDS 32 |
@@ -45,6 +47,12 @@ struct pcm_info { | |||
45 | volatile struct dbdma_regs __iomem *dbdma; | 47 | volatile struct dbdma_regs __iomem *dbdma; |
46 | }; | 48 | }; |
47 | 49 | ||
50 | enum { | ||
51 | aoa_resource_i2smmio = 0, | ||
52 | aoa_resource_txdbdma, | ||
53 | aoa_resource_rxdbdma, | ||
54 | }; | ||
55 | |||
48 | struct i2sbus_dev { | 56 | struct i2sbus_dev { |
49 | struct soundbus_dev sound; | 57 | struct soundbus_dev sound; |
50 | struct macio_dev *macio; | 58 | struct macio_dev *macio; |