0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define AW2_SAA7146_M
0012
0013 #include <linux/init.h>
0014 #include <linux/pci.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/delay.h>
0017 #include <linux/io.h>
0018 #include <sound/core.h>
0019 #include <sound/initval.h>
0020 #include <sound/pcm.h>
0021 #include <sound/pcm_params.h>
0022
0023 #include "saa7146.h"
0024 #include "aw2-saa7146.h"
0025
0026 #include "aw2-tsl.c"
0027
0028 #define WRITEREG(value, addr) writel((value), chip->base_addr + (addr))
0029 #define READREG(addr) readl(chip->base_addr + (addr))
0030
0031 static struct snd_aw2_saa7146_cb_param
0032 arr_substream_it_playback_cb[NB_STREAM_PLAYBACK];
0033 static struct snd_aw2_saa7146_cb_param
0034 arr_substream_it_capture_cb[NB_STREAM_CAPTURE];
0035
0036 static int snd_aw2_saa7146_get_limit(int size);
0037
0038
0039 int snd_aw2_saa7146_free(struct snd_aw2_saa7146 *chip)
0040 {
0041
0042 WRITEREG(0, IER);
0043
0044
0045 WRITEREG((MRST_N << 16), MC1);
0046
0047
0048 chip->base_addr = NULL;
0049
0050 return 0;
0051 }
0052
0053 void snd_aw2_saa7146_setup(struct snd_aw2_saa7146 *chip,
0054 void __iomem *pci_base_addr)
0055 {
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 unsigned int acon2;
0077 unsigned int acon1 = 0;
0078 int i;
0079
0080
0081 chip->base_addr = pci_base_addr;
0082
0083
0084 WRITEREG(0, IER);
0085
0086
0087 WRITEREG((MRST_N << 16), MC1);
0088
0089
0090 #ifdef __BIG_ENDIAN
0091 acon1 |= A1_SWAP;
0092 acon1 |= A2_SWAP;
0093 #endif
0094
0095
0096
0097 acon1 |= 0 * WS1_CTRL;
0098 acon1 |= 0 * WS2_CTRL;
0099
0100
0101
0102 acon1 |= 3 * WS4_CTRL;
0103
0104
0105 acon1 |= 2 * WS3_CTRL;
0106
0107
0108 acon1 |= 3 * AUDIO_MODE;
0109 WRITEREG(acon1, ACON1);
0110
0111
0112
0113
0114 WRITEREG(3 * (BurstA1_in) + 3 * (ThreshA1_in) +
0115 3 * (BurstA1_out) + 3 * (ThreshA1_out) +
0116 3 * (BurstA2_out) + 3 * (ThreshA2_out), PCI_BT_A);
0117
0118
0119 WRITEREG((EAP << 16) | EAP, MC1);
0120
0121
0122 WRITEREG((EI2C << 16) | EI2C, MC1);
0123
0124 WRITEREG(A1_out | A2_out | A1_in | IIC_S | IIC_E, IER);
0125
0126
0127 acon2 = A2_CLKSRC | BCLK1_OEN;
0128 WRITEREG(acon2, ACON2);
0129
0130
0131 snd_aw2_saa7146_use_digital_input(chip, 0);
0132
0133
0134 for (i = 0; i < 8; ++i) {
0135 WRITEREG(tsl1[i], TSL1 + (i * 4));
0136 WRITEREG(tsl2[i], TSL2 + (i * 4));
0137 }
0138
0139 }
0140
0141 void snd_aw2_saa7146_pcm_init_playback(struct snd_aw2_saa7146 *chip,
0142 int stream_number,
0143 unsigned long dma_addr,
0144 unsigned long period_size,
0145 unsigned long buffer_size)
0146 {
0147 unsigned long dw_page, dw_limit;
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 dw_page = (0L << 11);
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 dw_limit = snd_aw2_saa7146_get_limit(period_size);
0170 dw_page |= (dw_limit << 4);
0171
0172 if (stream_number == 0) {
0173 WRITEREG(dw_page, PageA2_out);
0174
0175
0176
0177
0178 WRITEREG(dma_addr, BaseA2_out);
0179
0180
0181 WRITEREG(dma_addr + buffer_size, ProtA2_out);
0182
0183 } else if (stream_number == 1) {
0184 WRITEREG(dw_page, PageA1_out);
0185
0186
0187
0188
0189 WRITEREG(dma_addr, BaseA1_out);
0190
0191
0192 WRITEREG(dma_addr + buffer_size, ProtA1_out);
0193 } else {
0194 pr_err("aw2: snd_aw2_saa7146_pcm_init_playback: "
0195 "Substream number is not 0 or 1 -> not managed\n");
0196 }
0197 }
0198
0199 void snd_aw2_saa7146_pcm_init_capture(struct snd_aw2_saa7146 *chip,
0200 int stream_number, unsigned long dma_addr,
0201 unsigned long period_size,
0202 unsigned long buffer_size)
0203 {
0204 unsigned long dw_page, dw_limit;
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214 dw_page = (0L << 11);
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226 dw_limit = snd_aw2_saa7146_get_limit(period_size);
0227 dw_page |= (dw_limit << 4);
0228
0229 if (stream_number == 0) {
0230 WRITEREG(dw_page, PageA1_in);
0231
0232
0233
0234
0235 WRITEREG(dma_addr, BaseA1_in);
0236
0237
0238 WRITEREG(dma_addr + buffer_size, ProtA1_in);
0239 } else {
0240 pr_err("aw2: snd_aw2_saa7146_pcm_init_capture: "
0241 "Substream number is not 0 -> not managed\n");
0242 }
0243 }
0244
0245 void snd_aw2_saa7146_define_it_playback_callback(unsigned int stream_number,
0246 snd_aw2_saa7146_it_cb
0247 p_it_callback,
0248 void *p_callback_param)
0249 {
0250 if (stream_number < NB_STREAM_PLAYBACK) {
0251 arr_substream_it_playback_cb[stream_number].p_it_callback =
0252 (snd_aw2_saa7146_it_cb) p_it_callback;
0253 arr_substream_it_playback_cb[stream_number].p_callback_param =
0254 (void *)p_callback_param;
0255 }
0256 }
0257
0258 void snd_aw2_saa7146_define_it_capture_callback(unsigned int stream_number,
0259 snd_aw2_saa7146_it_cb
0260 p_it_callback,
0261 void *p_callback_param)
0262 {
0263 if (stream_number < NB_STREAM_CAPTURE) {
0264 arr_substream_it_capture_cb[stream_number].p_it_callback =
0265 (snd_aw2_saa7146_it_cb) p_it_callback;
0266 arr_substream_it_capture_cb[stream_number].p_callback_param =
0267 (void *)p_callback_param;
0268 }
0269 }
0270
0271 void snd_aw2_saa7146_pcm_trigger_start_playback(struct snd_aw2_saa7146 *chip,
0272 int stream_number)
0273 {
0274 unsigned int acon1 = 0;
0275
0276
0277 acon1 = READREG(ACON1);
0278 if (stream_number == 0) {
0279 WRITEREG((TR_E_A2_OUT << 16) | TR_E_A2_OUT, MC1);
0280
0281
0282 acon1 |= 2 * WS2_CTRL;
0283 WRITEREG(acon1, ACON1);
0284
0285 } else if (stream_number == 1) {
0286 WRITEREG((TR_E_A1_OUT << 16) | TR_E_A1_OUT, MC1);
0287
0288
0289 acon1 |= 1 * WS1_CTRL;
0290 WRITEREG(acon1, ACON1);
0291 }
0292 }
0293
0294 void snd_aw2_saa7146_pcm_trigger_stop_playback(struct snd_aw2_saa7146 *chip,
0295 int stream_number)
0296 {
0297 unsigned int acon1 = 0;
0298 acon1 = READREG(ACON1);
0299 if (stream_number == 0) {
0300
0301 acon1 &= ~(3 * WS2_CTRL);
0302 WRITEREG(acon1, ACON1);
0303
0304 WRITEREG((TR_E_A2_OUT << 16), MC1);
0305 } else if (stream_number == 1) {
0306
0307 acon1 &= ~(3 * WS1_CTRL);
0308 WRITEREG(acon1, ACON1);
0309
0310 WRITEREG((TR_E_A1_OUT << 16), MC1);
0311 }
0312 }
0313
0314 void snd_aw2_saa7146_pcm_trigger_start_capture(struct snd_aw2_saa7146 *chip,
0315 int stream_number)
0316 {
0317
0318
0319 if (stream_number == 0)
0320 WRITEREG((TR_E_A1_IN << 16) | TR_E_A1_IN, MC1);
0321 }
0322
0323 void snd_aw2_saa7146_pcm_trigger_stop_capture(struct snd_aw2_saa7146 *chip,
0324 int stream_number)
0325 {
0326 if (stream_number == 0)
0327 WRITEREG((TR_E_A1_IN << 16), MC1);
0328 }
0329
0330 irqreturn_t snd_aw2_saa7146_interrupt(int irq, void *dev_id)
0331 {
0332 unsigned int isr;
0333 __always_unused unsigned int iicsta;
0334 struct snd_aw2_saa7146 *chip = dev_id;
0335
0336 isr = READREG(ISR);
0337 if (!isr)
0338 return IRQ_NONE;
0339
0340 WRITEREG(isr, ISR);
0341
0342 if (isr & (IIC_S | IIC_E)) {
0343 iicsta = READREG(IICSTA);
0344 WRITEREG(0x100, IICSTA);
0345 }
0346
0347 if (isr & A1_out) {
0348 if (arr_substream_it_playback_cb[1].p_it_callback != NULL) {
0349 arr_substream_it_playback_cb[1].
0350 p_it_callback(arr_substream_it_playback_cb[1].
0351 p_callback_param);
0352 }
0353 }
0354 if (isr & A2_out) {
0355 if (arr_substream_it_playback_cb[0].p_it_callback != NULL) {
0356 arr_substream_it_playback_cb[0].
0357 p_it_callback(arr_substream_it_playback_cb[0].
0358 p_callback_param);
0359 }
0360
0361 }
0362 if (isr & A1_in) {
0363 if (arr_substream_it_capture_cb[0].p_it_callback != NULL) {
0364 arr_substream_it_capture_cb[0].
0365 p_it_callback(arr_substream_it_capture_cb[0].
0366 p_callback_param);
0367 }
0368 }
0369 return IRQ_HANDLED;
0370 }
0371
0372 unsigned int snd_aw2_saa7146_get_hw_ptr_playback(struct snd_aw2_saa7146 *chip,
0373 int stream_number,
0374 unsigned char *start_addr,
0375 unsigned int buffer_size)
0376 {
0377 long pci_adp = 0;
0378 size_t ptr = 0;
0379
0380 if (stream_number == 0) {
0381 pci_adp = READREG(PCI_ADP3);
0382 ptr = pci_adp - (long)start_addr;
0383
0384 if (ptr == buffer_size)
0385 ptr = 0;
0386 }
0387 if (stream_number == 1) {
0388 pci_adp = READREG(PCI_ADP1);
0389 ptr = pci_adp - (size_t) start_addr;
0390
0391 if (ptr == buffer_size)
0392 ptr = 0;
0393 }
0394 return ptr;
0395 }
0396
0397 unsigned int snd_aw2_saa7146_get_hw_ptr_capture(struct snd_aw2_saa7146 *chip,
0398 int stream_number,
0399 unsigned char *start_addr,
0400 unsigned int buffer_size)
0401 {
0402 size_t pci_adp = 0;
0403 size_t ptr = 0;
0404 if (stream_number == 0) {
0405 pci_adp = READREG(PCI_ADP2);
0406 ptr = pci_adp - (size_t) start_addr;
0407
0408 if (ptr == buffer_size)
0409 ptr = 0;
0410 }
0411 return ptr;
0412 }
0413
0414 void snd_aw2_saa7146_use_digital_input(struct snd_aw2_saa7146 *chip,
0415 int use_digital)
0416 {
0417
0418
0419
0420
0421
0422
0423 if (use_digital)
0424 WRITEREG(0x40, GPIO_CTRL);
0425 else
0426 WRITEREG(0x50, GPIO_CTRL);
0427 }
0428
0429 int snd_aw2_saa7146_is_using_digital_input(struct snd_aw2_saa7146 *chip)
0430 {
0431 unsigned int reg_val = READREG(GPIO_CTRL);
0432 if ((reg_val & 0xFF) == 0x40)
0433 return 1;
0434 else
0435 return 0;
0436 }
0437
0438
0439 static int snd_aw2_saa7146_get_limit(int size)
0440 {
0441 int limitsize = 32;
0442 int limit = 0;
0443 while (limitsize < size) {
0444 limitsize *= 2;
0445 limit++;
0446 }
0447 return limit;
0448 }