0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "hpi_internal.h"
0013 #include "hpi_version.h"
0014 #include "hpimsginit.h"
0015 #include "hpioctl.h"
0016 #include "hpicmn.h"
0017
0018 #include <linux/pci.h>
0019 #include <linux/init.h>
0020 #include <linux/jiffies.h>
0021 #include <linux/slab.h>
0022 #include <linux/time.h>
0023 #include <linux/wait.h>
0024 #include <linux/module.h>
0025 #include <sound/core.h>
0026 #include <sound/control.h>
0027 #include <sound/pcm.h>
0028 #include <sound/pcm_params.h>
0029 #include <sound/info.h>
0030 #include <sound/initval.h>
0031 #include <sound/tlv.h>
0032 #include <sound/hwdep.h>
0033
0034 MODULE_LICENSE("GPL");
0035 MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
0036 MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx "
0037 HPI_VER_STRING);
0038
0039 #if defined CONFIG_SND_DEBUG_VERBOSE
0040
0041
0042
0043
0044
0045
0046
0047
0048 #define snd_printddd(format, args...) \
0049 __snd_printk(3, __FILE__, __LINE__, format, ##args)
0050 #else
0051 #define snd_printddd(format, args...) do { } while (0)
0052 #endif
0053
0054 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
0055 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
0056 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
0057 static bool enable_hpi_hwdep = 1;
0058
0059 module_param_array(index, int, NULL, 0444);
0060 MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
0061
0062 module_param_array(id, charp, NULL, 0444);
0063 MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
0064
0065 module_param_array(enable, bool, NULL, 0444);
0066 MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
0067
0068 module_param(enable_hpi_hwdep, bool, 0644);
0069 MODULE_PARM_DESC(enable_hpi_hwdep,
0070 "ALSA enable HPI hwdep for AudioScience soundcard ");
0071
0072
0073 #ifdef KERNEL_ALSA_BUILD
0074 static char *build_info = "Built using headers from kernel source";
0075 module_param(build_info, charp, 0444);
0076 MODULE_PARM_DESC(build_info, "Built using headers from kernel source");
0077 #else
0078 static char *build_info = "Built within ALSA source";
0079 module_param(build_info, charp, 0444);
0080 MODULE_PARM_DESC(build_info, "Built within ALSA source");
0081 #endif
0082
0083
0084 static const int mixer_dump;
0085
0086 #define DEFAULT_SAMPLERATE 44100
0087 static int adapter_fs = DEFAULT_SAMPLERATE;
0088
0089
0090 #define PERIODS_MIN 2
0091 #define PERIOD_BYTES_MIN 2048
0092 #define BUFFER_BYTES_MAX (512 * 1024)
0093
0094 #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
0095
0096 struct clk_source {
0097 int source;
0098 int index;
0099 const char *name;
0100 };
0101
0102 struct clk_cache {
0103 int count;
0104 int has_local;
0105 struct clk_source s[MAX_CLOCKSOURCES];
0106 };
0107
0108
0109 struct snd_card_asihpi {
0110 struct snd_card *card;
0111 struct pci_dev *pci;
0112 struct hpi_adapter *hpi;
0113
0114
0115
0116
0117
0118
0119 struct snd_card_asihpi_pcm *llmode_streampriv;
0120 void (*pcm_start)(struct snd_pcm_substream *substream);
0121 void (*pcm_stop)(struct snd_pcm_substream *substream);
0122
0123 u32 h_mixer;
0124 struct clk_cache cc;
0125
0126 u16 can_dma;
0127 u16 support_grouping;
0128 u16 support_mrx;
0129 u16 update_interval_frames;
0130 u16 in_max_chans;
0131 u16 out_max_chans;
0132 u16 in_min_chans;
0133 u16 out_min_chans;
0134 };
0135
0136
0137 struct snd_card_asihpi_pcm {
0138 struct timer_list timer;
0139 unsigned int respawn_timer;
0140 unsigned int hpi_buffer_attached;
0141 unsigned int buffer_bytes;
0142 unsigned int period_bytes;
0143 unsigned int bytes_per_sec;
0144 unsigned int pcm_buf_host_rw_ofs;
0145 unsigned int pcm_buf_dma_ofs;
0146 unsigned int pcm_buf_elapsed_dma_ofs;
0147 unsigned int drained_count;
0148 struct snd_pcm_substream *substream;
0149 u32 h_stream;
0150 struct hpi_format format;
0151 };
0152
0153
0154
0155
0156
0157 static u16 hpi_stream_host_buffer_attach(
0158 u32 h_stream,
0159 u32 size_in_bytes,
0160 u32 pci_address
0161 )
0162 {
0163 struct hpi_message hm;
0164 struct hpi_response hr;
0165 unsigned int obj = hpi_handle_object(h_stream);
0166
0167 if (!h_stream)
0168 return HPI_ERROR_INVALID_OBJ;
0169 hpi_init_message_response(&hm, &hr, obj,
0170 obj == HPI_OBJ_OSTREAM ?
0171 HPI_OSTREAM_HOSTBUFFER_ALLOC :
0172 HPI_ISTREAM_HOSTBUFFER_ALLOC);
0173
0174 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
0175 &hm.obj_index);
0176
0177 hm.u.d.u.buffer.buffer_size = size_in_bytes;
0178 hm.u.d.u.buffer.pci_address = pci_address;
0179 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
0180 hpi_send_recv(&hm, &hr);
0181 return hr.error;
0182 }
0183
0184 static u16 hpi_stream_host_buffer_detach(u32 h_stream)
0185 {
0186 struct hpi_message hm;
0187 struct hpi_response hr;
0188 unsigned int obj = hpi_handle_object(h_stream);
0189
0190 if (!h_stream)
0191 return HPI_ERROR_INVALID_OBJ;
0192
0193 hpi_init_message_response(&hm, &hr, obj,
0194 obj == HPI_OBJ_OSTREAM ?
0195 HPI_OSTREAM_HOSTBUFFER_FREE :
0196 HPI_ISTREAM_HOSTBUFFER_FREE);
0197
0198 hpi_handle_to_indexes(h_stream, &hm.adapter_index,
0199 &hm.obj_index);
0200 hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
0201 hpi_send_recv(&hm, &hr);
0202 return hr.error;
0203 }
0204
0205 static inline u16 hpi_stream_start(u32 h_stream)
0206 {
0207 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
0208 return hpi_outstream_start(h_stream);
0209 else
0210 return hpi_instream_start(h_stream);
0211 }
0212
0213 static inline u16 hpi_stream_stop(u32 h_stream)
0214 {
0215 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
0216 return hpi_outstream_stop(h_stream);
0217 else
0218 return hpi_instream_stop(h_stream);
0219 }
0220
0221 static inline u16 hpi_stream_get_info_ex(
0222 u32 h_stream,
0223 u16 *pw_state,
0224 u32 *pbuffer_size,
0225 u32 *pdata_in_buffer,
0226 u32 *psample_count,
0227 u32 *pauxiliary_data
0228 )
0229 {
0230 u16 e;
0231 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
0232 e = hpi_outstream_get_info_ex(h_stream, pw_state,
0233 pbuffer_size, pdata_in_buffer,
0234 psample_count, pauxiliary_data);
0235 else
0236 e = hpi_instream_get_info_ex(h_stream, pw_state,
0237 pbuffer_size, pdata_in_buffer,
0238 psample_count, pauxiliary_data);
0239 return e;
0240 }
0241
0242 static inline u16 hpi_stream_group_add(
0243 u32 h_master,
0244 u32 h_stream)
0245 {
0246 if (hpi_handle_object(h_master) == HPI_OBJ_OSTREAM)
0247 return hpi_outstream_group_add(h_master, h_stream);
0248 else
0249 return hpi_instream_group_add(h_master, h_stream);
0250 }
0251
0252 static inline u16 hpi_stream_group_reset(u32 h_stream)
0253 {
0254 if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM)
0255 return hpi_outstream_group_reset(h_stream);
0256 else
0257 return hpi_instream_group_reset(h_stream);
0258 }
0259
0260 static u16 handle_error(u16 err, int line, char *filename)
0261 {
0262 if (err)
0263 printk(KERN_WARNING
0264 "in file %s, line %d: HPI error %d\n",
0265 filename, line, err);
0266 return err;
0267 }
0268
0269 #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
0270
0271
0272
0273 static void print_hwparams(struct snd_pcm_substream *substream,
0274 struct snd_pcm_hw_params *p)
0275 {
0276 char name[16];
0277 snd_pcm_debug_name(substream, name, sizeof(name));
0278 snd_printdd("%s HWPARAMS\n", name);
0279 snd_printdd(" samplerate=%dHz channels=%d format=%d subformat=%d\n",
0280 params_rate(p), params_channels(p),
0281 params_format(p), params_subformat(p));
0282 snd_printdd(" buffer=%dB period=%dB period_size=%dB periods=%d\n",
0283 params_buffer_bytes(p), params_period_bytes(p),
0284 params_period_size(p), params_periods(p));
0285 snd_printdd(" buffer_size=%d access=%d data_rate=%dB/s\n",
0286 params_buffer_size(p), params_access(p),
0287 params_rate(p) * params_channels(p) *
0288 snd_pcm_format_width(params_format(p)) / 8);
0289 }
0290
0291 #define INVALID_FORMAT (__force snd_pcm_format_t)(-1)
0292
0293 static const snd_pcm_format_t hpi_to_alsa_formats[] = {
0294 INVALID_FORMAT,
0295 SNDRV_PCM_FORMAT_U8,
0296 SNDRV_PCM_FORMAT_S16,
0297 INVALID_FORMAT,
0298 SNDRV_PCM_FORMAT_MPEG,
0299 SNDRV_PCM_FORMAT_MPEG,
0300 INVALID_FORMAT,
0301 INVALID_FORMAT,
0302 SNDRV_PCM_FORMAT_S16_BE,
0303 INVALID_FORMAT,
0304 INVALID_FORMAT,
0305 SNDRV_PCM_FORMAT_S32,
0306 INVALID_FORMAT,
0307 INVALID_FORMAT,
0308 SNDRV_PCM_FORMAT_FLOAT,
0309 #if 1
0310
0311
0312
0313 INVALID_FORMAT
0314 #else
0315
0316 #endif
0317 };
0318
0319
0320 static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
0321 u16 *hpi_format)
0322 {
0323 u16 format;
0324
0325 for (format = HPI_FORMAT_PCM8_UNSIGNED;
0326 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
0327 if (hpi_to_alsa_formats[format] == alsa_format) {
0328 *hpi_format = format;
0329 return 0;
0330 }
0331 }
0332
0333 snd_printd(KERN_WARNING "failed match for alsa format %d\n",
0334 alsa_format);
0335 *hpi_format = 0;
0336 return -EINVAL;
0337 }
0338
0339 static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
0340 struct snd_pcm_hardware *pcmhw)
0341 {
0342 u16 err;
0343 u32 h_control;
0344 u32 sample_rate;
0345 int idx;
0346 unsigned int rate_min = 200000;
0347 unsigned int rate_max = 0;
0348 unsigned int rates = 0;
0349
0350 if (asihpi->support_mrx) {
0351 rates |= SNDRV_PCM_RATE_CONTINUOUS;
0352 rates |= SNDRV_PCM_RATE_8000_96000;
0353 rate_min = 8000;
0354 rate_max = 100000;
0355 } else {
0356
0357
0358 err = hpi_mixer_get_control(asihpi->h_mixer,
0359 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
0360 HPI_CONTROL_SAMPLECLOCK, &h_control);
0361 if (err) {
0362 dev_err(&asihpi->pci->dev,
0363 "No local sampleclock, err %d\n", err);
0364 }
0365
0366 for (idx = -1; idx < 100; idx++) {
0367 if (idx == -1) {
0368 if (hpi_sample_clock_get_sample_rate(h_control,
0369 &sample_rate))
0370 continue;
0371 } else if (hpi_sample_clock_query_local_rate(h_control,
0372 idx, &sample_rate)) {
0373 break;
0374 }
0375
0376 rate_min = min(rate_min, sample_rate);
0377 rate_max = max(rate_max, sample_rate);
0378
0379 switch (sample_rate) {
0380 case 5512:
0381 rates |= SNDRV_PCM_RATE_5512;
0382 break;
0383 case 8000:
0384 rates |= SNDRV_PCM_RATE_8000;
0385 break;
0386 case 11025:
0387 rates |= SNDRV_PCM_RATE_11025;
0388 break;
0389 case 16000:
0390 rates |= SNDRV_PCM_RATE_16000;
0391 break;
0392 case 22050:
0393 rates |= SNDRV_PCM_RATE_22050;
0394 break;
0395 case 32000:
0396 rates |= SNDRV_PCM_RATE_32000;
0397 break;
0398 case 44100:
0399 rates |= SNDRV_PCM_RATE_44100;
0400 break;
0401 case 48000:
0402 rates |= SNDRV_PCM_RATE_48000;
0403 break;
0404 case 64000:
0405 rates |= SNDRV_PCM_RATE_64000;
0406 break;
0407 case 88200:
0408 rates |= SNDRV_PCM_RATE_88200;
0409 break;
0410 case 96000:
0411 rates |= SNDRV_PCM_RATE_96000;
0412 break;
0413 case 176400:
0414 rates |= SNDRV_PCM_RATE_176400;
0415 break;
0416 case 192000:
0417 rates |= SNDRV_PCM_RATE_192000;
0418 break;
0419 default:
0420 rates |= SNDRV_PCM_RATE_KNOT;
0421 }
0422 }
0423 }
0424
0425 pcmhw->rates = rates;
0426 pcmhw->rate_min = rate_min;
0427 pcmhw->rate_max = rate_max;
0428 }
0429
0430 static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
0431 struct snd_pcm_hw_params *params)
0432 {
0433 struct snd_pcm_runtime *runtime = substream->runtime;
0434 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0435 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
0436 int err;
0437 u16 format;
0438 int width;
0439 unsigned int bytes_per_sec;
0440
0441 print_hwparams(substream, params);
0442 err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
0443 if (err)
0444 return err;
0445
0446 hpi_handle_error(hpi_format_create(&dpcm->format,
0447 params_channels(params),
0448 format, params_rate(params), 0, 0));
0449
0450 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
0451 if (hpi_instream_reset(dpcm->h_stream) != 0)
0452 return -EINVAL;
0453
0454 if (hpi_instream_set_format(
0455 dpcm->h_stream, &dpcm->format) != 0)
0456 return -EINVAL;
0457 }
0458
0459 dpcm->hpi_buffer_attached = 0;
0460 if (card->can_dma) {
0461 err = hpi_stream_host_buffer_attach(dpcm->h_stream,
0462 params_buffer_bytes(params), runtime->dma_addr);
0463 if (err == 0) {
0464 snd_printdd(
0465 "stream_host_buffer_attach success %u %lu\n",
0466 params_buffer_bytes(params),
0467 (unsigned long)runtime->dma_addr);
0468 } else {
0469 snd_printd("stream_host_buffer_attach error %d\n",
0470 err);
0471 return -ENOMEM;
0472 }
0473
0474 err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
0475 &dpcm->hpi_buffer_attached, NULL, NULL, NULL);
0476 }
0477 bytes_per_sec = params_rate(params) * params_channels(params);
0478 width = snd_pcm_format_width(params_format(params));
0479 bytes_per_sec *= width;
0480 bytes_per_sec /= 8;
0481 if (width < 0 || bytes_per_sec == 0)
0482 return -EINVAL;
0483
0484 dpcm->bytes_per_sec = bytes_per_sec;
0485 dpcm->buffer_bytes = params_buffer_bytes(params);
0486 dpcm->period_bytes = params_period_bytes(params);
0487
0488 return 0;
0489 }
0490
0491 static int
0492 snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
0493 {
0494 struct snd_pcm_runtime *runtime = substream->runtime;
0495 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0496 if (dpcm->hpi_buffer_attached)
0497 hpi_stream_host_buffer_detach(dpcm->h_stream);
0498
0499 return 0;
0500 }
0501
0502 static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
0503 {
0504 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0505 kfree(dpcm);
0506 }
0507
0508 static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
0509 substream)
0510 {
0511 struct snd_pcm_runtime *runtime = substream->runtime;
0512 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0513 int expiry;
0514
0515 expiry = HZ / 200;
0516
0517 expiry = max(expiry, 1);
0518 mod_timer(&dpcm->timer, jiffies + expiry);
0519 dpcm->respawn_timer = 1;
0520 }
0521
0522 static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
0523 {
0524 struct snd_pcm_runtime *runtime = substream->runtime;
0525 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0526
0527 dpcm->respawn_timer = 0;
0528 del_timer(&dpcm->timer);
0529 }
0530
0531 static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
0532 {
0533 struct snd_card_asihpi_pcm *dpcm;
0534 struct snd_card_asihpi *card;
0535
0536 dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data;
0537 card = snd_pcm_substream_chip(substream);
0538
0539 WARN_ON(in_interrupt());
0540 card->llmode_streampriv = dpcm;
0541
0542 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
0543 HPI_ADAPTER_PROPERTY_IRQ_RATE,
0544 card->update_interval_frames, 0));
0545 }
0546
0547 static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
0548 {
0549 struct snd_card_asihpi *card;
0550
0551 card = snd_pcm_substream_chip(substream);
0552
0553 hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
0554 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
0555
0556 card->llmode_streampriv = NULL;
0557 }
0558
0559 static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
0560 int cmd)
0561 {
0562 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
0563 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
0564 struct snd_pcm_substream *s;
0565 u16 e;
0566 char name[16];
0567
0568 snd_pcm_debug_name(substream, name, sizeof(name));
0569
0570 switch (cmd) {
0571 case SNDRV_PCM_TRIGGER_START:
0572 snd_printdd("%s trigger start\n", name);
0573 snd_pcm_group_for_each_entry(s, substream) {
0574 struct snd_pcm_runtime *runtime = s->runtime;
0575 struct snd_card_asihpi_pcm *ds = runtime->private_data;
0576
0577 if (snd_pcm_substream_chip(s) != card)
0578 continue;
0579
0580
0581 if (substream->stream != s->stream)
0582 continue;
0583
0584 ds->drained_count = 0;
0585 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0586
0587
0588
0589
0590
0591
0592 unsigned int preload = ds->period_bytes * 1;
0593 snd_printddd("%d preload %d\n", s->number, preload);
0594 hpi_handle_error(hpi_outstream_write_buf(
0595 ds->h_stream,
0596 &runtime->dma_area[0],
0597 preload,
0598 &ds->format));
0599 ds->pcm_buf_host_rw_ofs = preload;
0600 }
0601
0602 if (card->support_grouping) {
0603 snd_printdd("%d group\n", s->number);
0604 e = hpi_stream_group_add(
0605 dpcm->h_stream,
0606 ds->h_stream);
0607 if (!e) {
0608 snd_pcm_trigger_done(s, substream);
0609 } else {
0610 hpi_handle_error(e);
0611 break;
0612 }
0613 } else
0614 break;
0615 }
0616
0617 card->pcm_start(substream);
0618 if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
0619 !card->can_dma)
0620 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
0621 break;
0622
0623 case SNDRV_PCM_TRIGGER_STOP:
0624 snd_printdd("%s trigger stop\n", name);
0625 card->pcm_stop(substream);
0626 snd_pcm_group_for_each_entry(s, substream) {
0627 if (snd_pcm_substream_chip(s) != card)
0628 continue;
0629
0630 if (substream->stream != s->stream)
0631 continue;
0632
0633
0634
0635 s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
0636
0637 if (card->support_grouping) {
0638 snd_printdd("%d group\n", s->number);
0639 snd_pcm_trigger_done(s, substream);
0640 } else
0641 break;
0642 }
0643
0644
0645 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
0646 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0647 hpi_handle_error(
0648 hpi_outstream_reset(dpcm->h_stream));
0649
0650 if (card->support_grouping)
0651 hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
0652 break;
0653
0654 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0655 snd_printdd("%s trigger pause release\n", name);
0656 card->pcm_start(substream);
0657 hpi_handle_error(hpi_stream_start(dpcm->h_stream));
0658 break;
0659 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0660 snd_printdd("%s trigger pause push\n", name);
0661 card->pcm_stop(substream);
0662 hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
0663 break;
0664 default:
0665 snd_printd(KERN_ERR "\tINVALID\n");
0666 return -EINVAL;
0667 }
0668
0669 return 0;
0670 }
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703 static inline unsigned int modulo_min(unsigned int a, unsigned int b,
0704 unsigned long int modulus)
0705 {
0706 unsigned int result;
0707 if (((a-b) % modulus) < (modulus/2))
0708 result = b;
0709 else
0710 result = a;
0711
0712 return result;
0713 }
0714
0715
0716
0717 static void snd_card_asihpi_timer_function(struct timer_list *t)
0718 {
0719 struct snd_card_asihpi_pcm *dpcm = from_timer(dpcm, t, timer);
0720 struct snd_pcm_substream *substream = dpcm->substream;
0721 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
0722 struct snd_pcm_runtime *runtime;
0723 struct snd_pcm_substream *s;
0724 unsigned int newdata = 0;
0725 unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
0726 unsigned int remdata, xfercount, next_jiffies;
0727 int first = 1;
0728 int loops = 0;
0729 u16 state;
0730 u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
0731 char name[16];
0732
0733
0734 snd_pcm_debug_name(substream, name, sizeof(name));
0735
0736
0737 snd_pcm_group_for_each_entry(s, substream) {
0738 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
0739 runtime = s->runtime;
0740
0741 if (snd_pcm_substream_chip(s) != card)
0742 continue;
0743
0744
0745 if (substream->stream != s->stream)
0746 continue;
0747
0748 hpi_handle_error(hpi_stream_get_info_ex(
0749 ds->h_stream, &state,
0750 &buffer_size, &bytes_avail,
0751 &samples_played, &on_card_bytes));
0752
0753
0754 runtime->delay = on_card_bytes;
0755
0756 if (!card->can_dma)
0757 on_card_bytes = bytes_avail;
0758
0759 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0760 pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
0761 if (state == HPI_STATE_STOPPED) {
0762 if (bytes_avail == 0) {
0763 hpi_handle_error(hpi_stream_start(ds->h_stream));
0764 snd_printdd("P%d start\n", s->number);
0765 ds->drained_count = 0;
0766 }
0767 } else if (state == HPI_STATE_DRAINED) {
0768 snd_printd(KERN_WARNING "P%d drained\n",
0769 s->number);
0770 ds->drained_count++;
0771 if (ds->drained_count > 20) {
0772 snd_pcm_stop_xrun(s);
0773 continue;
0774 }
0775 } else {
0776 ds->drained_count = 0;
0777 }
0778 } else
0779 pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
0780
0781 if (first) {
0782
0783 min_buf_pos = pcm_buf_dma_ofs;
0784 newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
0785 first = 0;
0786 } else {
0787 min_buf_pos =
0788 modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
0789 newdata = min(
0790 (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
0791 newdata);
0792 }
0793
0794 snd_printddd(
0795 "timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n",
0796 name, s->number, state,
0797 ds->pcm_buf_elapsed_dma_ofs,
0798 ds->pcm_buf_host_rw_ofs,
0799 pcm_buf_dma_ofs,
0800 (int)bytes_avail,
0801
0802 (int)on_card_bytes,
0803 buffer_size-bytes_avail,
0804 (unsigned long)frames_to_bytes(runtime,
0805 runtime->status->hw_ptr),
0806 (unsigned long)frames_to_bytes(runtime,
0807 runtime->control->appl_ptr)
0808 );
0809 loops++;
0810 }
0811 pcm_buf_dma_ofs = min_buf_pos;
0812
0813 remdata = newdata % dpcm->period_bytes;
0814 xfercount = newdata - remdata;
0815
0816
0817
0818
0819 if (xfercount && (on_card_bytes > dpcm->period_bytes))
0820 next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
0821 else
0822 next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
0823
0824 next_jiffies = max(next_jiffies, 1U);
0825 dpcm->timer.expires = jiffies + next_jiffies;
0826 snd_printddd("timer2, jif=%d, buf_pos=%d, newdata=%d, xfer=%d\n",
0827 next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
0828
0829 snd_pcm_group_for_each_entry(s, substream) {
0830 struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
0831
0832
0833 if (substream->stream != s->stream)
0834 continue;
0835
0836
0837 ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
0838
0839 if (xfercount &&
0840
0841 ((on_card_bytes <= ds->period_bytes) ||
0842 (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
0843
0844 {
0845
0846 unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
0847 unsigned int xfer1, xfer2;
0848 char *pd = &s->runtime->dma_area[buf_ofs];
0849
0850 if (card->can_dma) {
0851 xfer1 = xfercount;
0852 xfer2 = 0;
0853 } else {
0854 xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
0855 xfer2 = xfercount - xfer1;
0856 }
0857
0858 if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
0859 snd_printddd("write1, P=%d, xfer=%d, buf_ofs=%d\n",
0860 s->number, xfer1, buf_ofs);
0861 hpi_handle_error(
0862 hpi_outstream_write_buf(
0863 ds->h_stream, pd, xfer1,
0864 &ds->format));
0865
0866 if (xfer2) {
0867 pd = s->runtime->dma_area;
0868
0869 snd_printddd("write2, P=%d, xfer=%d, buf_ofs=%d\n",
0870 s->number,
0871 xfercount - xfer1, buf_ofs);
0872 hpi_handle_error(
0873 hpi_outstream_write_buf(
0874 ds->h_stream, pd,
0875 xfercount - xfer1,
0876 &ds->format));
0877 }
0878 } else {
0879 snd_printddd("read1, C=%d, xfer=%d\n",
0880 s->number, xfer1);
0881 hpi_handle_error(
0882 hpi_instream_read_buf(
0883 ds->h_stream,
0884 pd, xfer1));
0885 if (xfer2) {
0886 pd = s->runtime->dma_area;
0887 snd_printddd("read2, C=%d, xfer=%d\n",
0888 s->number, xfer2);
0889 hpi_handle_error(
0890 hpi_instream_read_buf(
0891 ds->h_stream,
0892 pd, xfer2));
0893 }
0894 }
0895
0896 ds->pcm_buf_host_rw_ofs += xfercount;
0897 ds->pcm_buf_elapsed_dma_ofs += xfercount;
0898 snd_pcm_period_elapsed(s);
0899 }
0900 }
0901
0902 if (!card->hpi->interrupt_mode && dpcm->respawn_timer)
0903 add_timer(&dpcm->timer);
0904 }
0905
0906 static void snd_card_asihpi_isr(struct hpi_adapter *a)
0907 {
0908 struct snd_card_asihpi *asihpi;
0909
0910 WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
0911 asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
0912 if (asihpi->llmode_streampriv)
0913 snd_card_asihpi_timer_function(
0914 &asihpi->llmode_streampriv->timer);
0915 }
0916
0917
0918 static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
0919 substream)
0920 {
0921 struct snd_pcm_runtime *runtime = substream->runtime;
0922 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0923
0924 snd_printdd("P%d prepare\n", substream->number);
0925
0926 hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
0927 dpcm->pcm_buf_host_rw_ofs = 0;
0928 dpcm->pcm_buf_dma_ofs = 0;
0929 dpcm->pcm_buf_elapsed_dma_ofs = 0;
0930 return 0;
0931 }
0932
0933 static snd_pcm_uframes_t
0934 snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
0935 {
0936 struct snd_pcm_runtime *runtime = substream->runtime;
0937 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
0938 snd_pcm_uframes_t ptr;
0939 char name[16];
0940 snd_pcm_debug_name(substream, name, sizeof(name));
0941
0942 ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
0943 snd_printddd("%s, pointer=%ld\n", name, (unsigned long)ptr);
0944 return ptr;
0945 }
0946
0947 static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
0948 u32 h_stream)
0949 {
0950 struct hpi_format hpi_format;
0951 u16 format;
0952 u16 err;
0953 u32 h_control;
0954 u32 sample_rate = 48000;
0955 u64 formats = 0;
0956
0957
0958
0959
0960 err = hpi_mixer_get_control(asihpi->h_mixer,
0961 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
0962 HPI_CONTROL_SAMPLECLOCK, &h_control);
0963
0964 if (!err)
0965 err = hpi_sample_clock_get_sample_rate(h_control,
0966 &sample_rate);
0967
0968 for (format = HPI_FORMAT_PCM8_UNSIGNED;
0969 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
0970 err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
0971 format, sample_rate, 128000, 0);
0972 if (!err)
0973 err = hpi_outstream_query_format(h_stream, &hpi_format);
0974 if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
0975 formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
0976 }
0977 return formats;
0978 }
0979
0980 static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
0981 {
0982 struct snd_pcm_runtime *runtime = substream->runtime;
0983 struct snd_card_asihpi_pcm *dpcm;
0984 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
0985 struct snd_pcm_hardware snd_card_asihpi_playback;
0986 int err;
0987
0988 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
0989 if (dpcm == NULL)
0990 return -ENOMEM;
0991
0992 err = hpi_outstream_open(card->hpi->adapter->index,
0993 substream->number, &dpcm->h_stream);
0994 hpi_handle_error(err);
0995 if (err)
0996 kfree(dpcm);
0997 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
0998 return -EBUSY;
0999 if (err)
1000 return -EIO;
1001
1002
1003
1004
1005
1006
1007 timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
1008 dpcm->substream = substream;
1009 runtime->private_data = dpcm;
1010 runtime->private_free = snd_card_asihpi_runtime_free;
1011
1012 memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback));
1013 if (!card->hpi->interrupt_mode) {
1014 snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
1015 snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN;
1016 snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1017 snd_card_asihpi_playback.periods_min = PERIODS_MIN;
1018 snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1019 } else {
1020 size_t pbmin = card->update_interval_frames *
1021 card->out_max_chans;
1022 snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX;
1023 snd_card_asihpi_playback.period_bytes_min = pbmin;
1024 snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1025 snd_card_asihpi_playback.periods_min = PERIODS_MIN;
1026 snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / pbmin;
1027 }
1028
1029
1030 snd_card_asihpi_playback.channels_max = card->out_max_chans;
1031 snd_card_asihpi_playback.channels_min = card->out_min_chans;
1032 snd_card_asihpi_playback.formats =
1033 snd_card_asihpi_playback_formats(card, dpcm->h_stream);
1034
1035 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback);
1036
1037 snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
1038 SNDRV_PCM_INFO_DOUBLE |
1039 SNDRV_PCM_INFO_BATCH |
1040 SNDRV_PCM_INFO_BLOCK_TRANSFER |
1041 SNDRV_PCM_INFO_PAUSE |
1042 SNDRV_PCM_INFO_MMAP |
1043 SNDRV_PCM_INFO_MMAP_VALID;
1044
1045 if (card->support_grouping) {
1046 snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
1047 snd_pcm_set_sync(substream);
1048 }
1049
1050
1051 runtime->hw = snd_card_asihpi_playback;
1052
1053 if (card->can_dma)
1054 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1055 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1056 if (err < 0)
1057 return err;
1058
1059 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1060 card->update_interval_frames);
1061
1062 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1063 card->update_interval_frames, UINT_MAX);
1064
1065 snd_printdd("playback open\n");
1066
1067 return 0;
1068 }
1069
1070 static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1071 {
1072 struct snd_pcm_runtime *runtime = substream->runtime;
1073 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1074
1075 hpi_handle_error(hpi_outstream_close(dpcm->h_stream));
1076 snd_printdd("playback close\n");
1077
1078 return 0;
1079 }
1080
1081 static const struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1082 .open = snd_card_asihpi_playback_open,
1083 .close = snd_card_asihpi_playback_close,
1084 .hw_params = snd_card_asihpi_pcm_hw_params,
1085 .hw_free = snd_card_asihpi_hw_free,
1086 .prepare = snd_card_asihpi_playback_prepare,
1087 .trigger = snd_card_asihpi_trigger,
1088 .pointer = snd_card_asihpi_playback_pointer,
1089 };
1090
1091
1092 static snd_pcm_uframes_t
1093 snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1094 {
1095 struct snd_pcm_runtime *runtime = substream->runtime;
1096 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1097 char name[16];
1098 snd_pcm_debug_name(substream, name, sizeof(name));
1099
1100 snd_printddd("%s, pointer=%d\n", name, dpcm->pcm_buf_dma_ofs);
1101
1102
1103
1104
1105 return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1106 }
1107
1108 static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1109 {
1110 struct snd_pcm_runtime *runtime = substream->runtime;
1111 struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1112
1113 hpi_handle_error(hpi_instream_reset(dpcm->h_stream));
1114 dpcm->pcm_buf_host_rw_ofs = 0;
1115 dpcm->pcm_buf_dma_ofs = 0;
1116 dpcm->pcm_buf_elapsed_dma_ofs = 0;
1117
1118 snd_printdd("Capture Prepare %d\n", substream->number);
1119 return 0;
1120 }
1121
1122 static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
1123 u32 h_stream)
1124 {
1125 struct hpi_format hpi_format;
1126 u16 format;
1127 u16 err;
1128 u32 h_control;
1129 u32 sample_rate = 48000;
1130 u64 formats = 0;
1131
1132
1133
1134 err = hpi_mixer_get_control(asihpi->h_mixer,
1135 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1136 HPI_CONTROL_SAMPLECLOCK, &h_control);
1137
1138 if (!err)
1139 err = hpi_sample_clock_get_sample_rate(h_control,
1140 &sample_rate);
1141
1142 for (format = HPI_FORMAT_PCM8_UNSIGNED;
1143 format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1144
1145 err = hpi_format_create(&hpi_format, asihpi->in_max_chans,
1146 format, sample_rate, 128000, 0);
1147 if (!err)
1148 err = hpi_instream_query_format(h_stream, &hpi_format);
1149 if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
1150 formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
1151 }
1152 return formats;
1153 }
1154
1155 static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1156 {
1157 struct snd_pcm_runtime *runtime = substream->runtime;
1158 struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1159 struct snd_card_asihpi_pcm *dpcm;
1160 struct snd_pcm_hardware snd_card_asihpi_capture;
1161 int err;
1162
1163 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1164 if (dpcm == NULL)
1165 return -ENOMEM;
1166
1167 snd_printdd("capture open adapter %d stream %d\n",
1168 card->hpi->adapter->index, substream->number);
1169
1170 err = hpi_handle_error(
1171 hpi_instream_open(card->hpi->adapter->index,
1172 substream->number, &dpcm->h_stream));
1173 if (err)
1174 kfree(dpcm);
1175 if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1176 return -EBUSY;
1177 if (err)
1178 return -EIO;
1179
1180 timer_setup(&dpcm->timer, snd_card_asihpi_timer_function, 0);
1181 dpcm->substream = substream;
1182 runtime->private_data = dpcm;
1183 runtime->private_free = snd_card_asihpi_runtime_free;
1184
1185 memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture));
1186 if (!card->hpi->interrupt_mode) {
1187 snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
1188 snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN;
1189 snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1190 snd_card_asihpi_capture.periods_min = PERIODS_MIN;
1191 snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN;
1192 } else {
1193 size_t pbmin = card->update_interval_frames *
1194 card->out_max_chans;
1195 snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX;
1196 snd_card_asihpi_capture.period_bytes_min = pbmin;
1197 snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN;
1198 snd_card_asihpi_capture.periods_min = PERIODS_MIN;
1199 snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / pbmin;
1200 }
1201
1202 snd_card_asihpi_capture.channels_max = card->in_max_chans;
1203 snd_card_asihpi_capture.channels_min = card->in_min_chans;
1204 snd_card_asihpi_capture.formats =
1205 snd_card_asihpi_capture_formats(card, dpcm->h_stream);
1206 snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture);
1207 snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED |
1208 SNDRV_PCM_INFO_MMAP |
1209 SNDRV_PCM_INFO_MMAP_VALID;
1210
1211 if (card->support_grouping)
1212 snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
1213
1214 runtime->hw = snd_card_asihpi_capture;
1215
1216 if (card->can_dma)
1217 err = snd_pcm_hw_constraint_pow2(runtime, 0,
1218 SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1219 if (err < 0)
1220 return err;
1221
1222 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1223 card->update_interval_frames);
1224 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1225 card->update_interval_frames, UINT_MAX);
1226
1227 snd_pcm_set_sync(substream);
1228
1229 return 0;
1230 }
1231
1232 static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1233 {
1234 struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1235
1236 hpi_handle_error(hpi_instream_close(dpcm->h_stream));
1237 return 0;
1238 }
1239
1240 static const struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1241 .open = snd_card_asihpi_capture_open,
1242 .close = snd_card_asihpi_capture_close,
1243 .hw_params = snd_card_asihpi_pcm_hw_params,
1244 .hw_free = snd_card_asihpi_hw_free,
1245 .prepare = snd_card_asihpi_capture_prepare,
1246 .trigger = snd_card_asihpi_trigger,
1247 .pointer = snd_card_asihpi_capture_pointer,
1248 };
1249
1250 static int snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device)
1251 {
1252 struct snd_pcm *pcm;
1253 int err;
1254 u16 num_instreams, num_outstreams, x16;
1255 u32 x32;
1256
1257 err = hpi_adapter_get_info(asihpi->hpi->adapter->index,
1258 &num_outstreams, &num_instreams,
1259 &x16, &x32, &x16);
1260
1261 err = snd_pcm_new(asihpi->card, "Asihpi PCM", device,
1262 num_outstreams, num_instreams, &pcm);
1263 if (err < 0)
1264 return err;
1265
1266
1267 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1268 &snd_card_asihpi_playback_mmap_ops);
1269 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1270 &snd_card_asihpi_capture_mmap_ops);
1271
1272 pcm->private_data = asihpi;
1273 pcm->info_flags = 0;
1274 strcpy(pcm->name, "Asihpi PCM");
1275
1276
1277
1278 snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
1279 &asihpi->pci->dev,
1280 64*1024, BUFFER_BYTES_MAX);
1281
1282 return 0;
1283 }
1284
1285
1286 struct hpi_control {
1287 u32 h_control;
1288 u16 control_type;
1289 u16 src_node_type;
1290 u16 src_node_index;
1291 u16 dst_node_type;
1292 u16 dst_node_index;
1293 u16 band;
1294 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
1295 };
1296
1297 static const char * const asihpi_tuner_band_names[] = {
1298 "invalid",
1299 "AM",
1300 "FM mono",
1301 "TV NTSC-M",
1302 "FM stereo",
1303 "AUX",
1304 "TV PAL BG",
1305 "TV PAL I",
1306 "TV PAL DK",
1307 "TV SECAM",
1308 "TV DAB",
1309 };
1310
1311 compile_time_assert(
1312 (ARRAY_SIZE(asihpi_tuner_band_names) ==
1313 (HPI_TUNER_BAND_LAST+1)),
1314 assert_tuner_band_names_size);
1315
1316 static const char * const asihpi_src_names[] = {
1317 "no source",
1318 "PCM",
1319 "Line",
1320 "Digital",
1321 "Tuner",
1322 "RF",
1323 "Clock",
1324 "Bitstream",
1325 "Mic",
1326 "Net",
1327 "Analog",
1328 "Adapter",
1329 "RTP",
1330 "Internal",
1331 "AVB",
1332 "BLU-Link"
1333 };
1334
1335 compile_time_assert(
1336 (ARRAY_SIZE(asihpi_src_names) ==
1337 (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1338 assert_src_names_size);
1339
1340 static const char * const asihpi_dst_names[] = {
1341 "no destination",
1342 "PCM",
1343 "Line",
1344 "Digital",
1345 "RF",
1346 "Speaker",
1347 "Net",
1348 "Analog",
1349 "RTP",
1350 "AVB",
1351 "Internal",
1352 "BLU-Link"
1353 };
1354
1355 compile_time_assert(
1356 (ARRAY_SIZE(asihpi_dst_names) ==
1357 (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1358 assert_dst_names_size);
1359
1360 static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1361 struct snd_card_asihpi *asihpi)
1362 {
1363 int err;
1364
1365 err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1366 if (err < 0)
1367 return err;
1368 else if (mixer_dump)
1369 dev_info(&asihpi->pci->dev, "added %s(%d)\n", ctl->name, ctl->index);
1370
1371 return 0;
1372 }
1373
1374
1375 static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1376 struct hpi_control *hpi_ctl,
1377 char *name)
1378 {
1379 char *dir;
1380 memset(snd_control, 0, sizeof(*snd_control));
1381 snd_control->name = hpi_ctl->name;
1382 snd_control->private_value = hpi_ctl->h_control;
1383 snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1384 snd_control->index = 0;
1385
1386 if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
1387 dir = "";
1388 else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1389 dir = "Capture ";
1390 else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1391 (!hpi_ctl->dst_node_type))
1392 dir = "Capture ";
1393 else if (hpi_ctl->src_node_type &&
1394 (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1395 (hpi_ctl->dst_node_type))
1396 dir = "Monitor Playback ";
1397 else
1398 dir = "Playback ";
1399
1400 if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1401 sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
1402 asihpi_src_names[hpi_ctl->src_node_type],
1403 hpi_ctl->src_node_index,
1404 asihpi_dst_names[hpi_ctl->dst_node_type],
1405 hpi_ctl->dst_node_index,
1406 dir, name);
1407 else if (hpi_ctl->dst_node_type) {
1408 sprintf(hpi_ctl->name, "%s %d %s%s",
1409 asihpi_dst_names[hpi_ctl->dst_node_type],
1410 hpi_ctl->dst_node_index,
1411 dir, name);
1412 } else {
1413 sprintf(hpi_ctl->name, "%s %d %s%s",
1414 asihpi_src_names[hpi_ctl->src_node_type],
1415 hpi_ctl->src_node_index,
1416 dir, name);
1417 }
1418
1419
1420 }
1421
1422
1423
1424
1425 #define VOL_STEP_mB 1
1426 static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1427 struct snd_ctl_elem_info *uinfo)
1428 {
1429 u32 h_control = kcontrol->private_value;
1430 u32 count;
1431 u16 err;
1432
1433 short min_gain_mB;
1434 short max_gain_mB;
1435 short step_gain_mB;
1436
1437 err = hpi_volume_query_range(h_control,
1438 &min_gain_mB, &max_gain_mB, &step_gain_mB);
1439 if (err) {
1440 max_gain_mB = 0;
1441 min_gain_mB = -10000;
1442 step_gain_mB = VOL_STEP_mB;
1443 }
1444
1445 err = hpi_meter_query_channels(h_control, &count);
1446 if (err)
1447 count = HPI_MAX_CHANNELS;
1448
1449 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1450 uinfo->count = count;
1451 uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1452 uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1453 uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1454 return 0;
1455 }
1456
1457 static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1458 struct snd_ctl_elem_value *ucontrol)
1459 {
1460 u32 h_control = kcontrol->private_value;
1461 short an_gain_mB[HPI_MAX_CHANNELS];
1462
1463 hpi_handle_error(hpi_volume_get_gain(h_control, an_gain_mB));
1464 ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1465 ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1466
1467 return 0;
1468 }
1469
1470 static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1471 struct snd_ctl_elem_value *ucontrol)
1472 {
1473 u32 h_control = kcontrol->private_value;
1474 short an_gain_mB[HPI_MAX_CHANNELS];
1475
1476 an_gain_mB[0] =
1477 (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1478 an_gain_mB[1] =
1479 (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1480
1481
1482
1483 hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1484 return 1;
1485 }
1486
1487 static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1488
1489 #define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
1490
1491 static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
1492 struct snd_ctl_elem_value *ucontrol)
1493 {
1494 u32 h_control = kcontrol->private_value;
1495 u32 mute;
1496
1497 hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
1498 ucontrol->value.integer.value[0] = mute ? 0 : 1;
1499
1500 return 0;
1501 }
1502
1503 static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
1504 struct snd_ctl_elem_value *ucontrol)
1505 {
1506 u32 h_control = kcontrol->private_value;
1507
1508
1509
1510 int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
1511 hpi_handle_error(hpi_volume_set_mute(h_control, mute));
1512 return 1;
1513 }
1514
1515 static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1516 struct hpi_control *hpi_ctl)
1517 {
1518 struct snd_card *card = asihpi->card;
1519 struct snd_kcontrol_new snd_control;
1520 int err;
1521 u32 mute;
1522
1523 asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
1524 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1525 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1526 snd_control.info = snd_asihpi_volume_info;
1527 snd_control.get = snd_asihpi_volume_get;
1528 snd_control.put = snd_asihpi_volume_put;
1529 snd_control.tlv.p = db_scale_100;
1530
1531 err = ctl_add(card, &snd_control, asihpi);
1532 if (err)
1533 return err;
1534
1535 if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
1536 asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
1537 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1538 snd_control.info = snd_asihpi_volume_mute_info;
1539 snd_control.get = snd_asihpi_volume_mute_get;
1540 snd_control.put = snd_asihpi_volume_mute_put;
1541 err = ctl_add(card, &snd_control, asihpi);
1542 }
1543 return err;
1544 }
1545
1546
1547
1548
1549 static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1550 struct snd_ctl_elem_info *uinfo)
1551 {
1552 u32 h_control = kcontrol->private_value;
1553 u16 err;
1554 short min_gain_mB;
1555 short max_gain_mB;
1556 short step_gain_mB;
1557
1558 err =
1559 hpi_level_query_range(h_control, &min_gain_mB,
1560 &max_gain_mB, &step_gain_mB);
1561 if (err) {
1562 max_gain_mB = 2400;
1563 min_gain_mB = -1000;
1564 step_gain_mB = 100;
1565 }
1566
1567 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1568 uinfo->count = 2;
1569 uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1570 uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1571 uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1572 return 0;
1573 }
1574
1575 static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1577 {
1578 u32 h_control = kcontrol->private_value;
1579 short an_gain_mB[HPI_MAX_CHANNELS];
1580
1581 hpi_handle_error(hpi_level_get_gain(h_control, an_gain_mB));
1582 ucontrol->value.integer.value[0] =
1583 an_gain_mB[0] / HPI_UNITS_PER_dB;
1584 ucontrol->value.integer.value[1] =
1585 an_gain_mB[1] / HPI_UNITS_PER_dB;
1586
1587 return 0;
1588 }
1589
1590 static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1591 struct snd_ctl_elem_value *ucontrol)
1592 {
1593 int change;
1594 u32 h_control = kcontrol->private_value;
1595 short an_gain_mB[HPI_MAX_CHANNELS];
1596
1597 an_gain_mB[0] =
1598 (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1599 an_gain_mB[1] =
1600 (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1601
1602
1603
1604 change = 1;
1605 hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1606 return change;
1607 }
1608
1609 static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611 static int snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1612 struct hpi_control *hpi_ctl)
1613 {
1614 struct snd_card *card = asihpi->card;
1615 struct snd_kcontrol_new snd_control;
1616
1617
1618 asihpi_ctl_init(&snd_control, hpi_ctl, "Level");
1619 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1621 snd_control.info = snd_asihpi_level_info;
1622 snd_control.get = snd_asihpi_level_get;
1623 snd_control.put = snd_asihpi_level_put;
1624 snd_control.tlv.p = db_scale_level;
1625
1626 return ctl_add(card, &snd_control, asihpi);
1627 }
1628
1629
1630
1631
1632
1633
1634 static const char * const asihpi_aesebu_format_names[] = {
1635 "N/A", "S/PDIF", "AES/EBU" };
1636
1637 static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1638 struct snd_ctl_elem_info *uinfo)
1639 {
1640 return snd_ctl_enum_info(uinfo, 1, 3, asihpi_aesebu_format_names);
1641 }
1642
1643 static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1644 struct snd_ctl_elem_value *ucontrol,
1645 u16 (*func)(u32, u16 *))
1646 {
1647 u32 h_control = kcontrol->private_value;
1648 u16 source, err;
1649
1650 err = func(h_control, &source);
1651
1652
1653 ucontrol->value.enumerated.item[0] = 0;
1654
1655 if (err)
1656 return 0;
1657 if (source == HPI_AESEBU_FORMAT_SPDIF)
1658 ucontrol->value.enumerated.item[0] = 1;
1659 if (source == HPI_AESEBU_FORMAT_AESEBU)
1660 ucontrol->value.enumerated.item[0] = 2;
1661
1662 return 0;
1663 }
1664
1665 static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1666 struct snd_ctl_elem_value *ucontrol,
1667 u16 (*func)(u32, u16))
1668 {
1669 u32 h_control = kcontrol->private_value;
1670
1671
1672 u16 source = HPI_AESEBU_FORMAT_SPDIF;
1673
1674 if (ucontrol->value.enumerated.item[0] == 1)
1675 source = HPI_AESEBU_FORMAT_SPDIF;
1676 if (ucontrol->value.enumerated.item[0] == 2)
1677 source = HPI_AESEBU_FORMAT_AESEBU;
1678
1679 if (func(h_control, source) != 0)
1680 return -EINVAL;
1681
1682 return 1;
1683 }
1684
1685 static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1686 struct snd_ctl_elem_value *ucontrol) {
1687 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1688 hpi_aesebu_receiver_get_format);
1689 }
1690
1691 static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1692 struct snd_ctl_elem_value *ucontrol) {
1693 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1694 hpi_aesebu_receiver_set_format);
1695 }
1696
1697 static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1698 struct snd_ctl_elem_info *uinfo)
1699 {
1700 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1701 uinfo->count = 1;
1702
1703 uinfo->value.integer.min = 0;
1704 uinfo->value.integer.max = 0X1F;
1705 uinfo->value.integer.step = 1;
1706
1707 return 0;
1708 }
1709
1710 static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1711 struct snd_ctl_elem_value *ucontrol) {
1712
1713 u32 h_control = kcontrol->private_value;
1714 u16 status;
1715
1716 hpi_handle_error(hpi_aesebu_receiver_get_error_status(
1717 h_control, &status));
1718 ucontrol->value.integer.value[0] = status;
1719 return 0;
1720 }
1721
1722 static int snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1723 struct hpi_control *hpi_ctl)
1724 {
1725 struct snd_card *card = asihpi->card;
1726 struct snd_kcontrol_new snd_control;
1727
1728 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1729 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1730 snd_control.info = snd_asihpi_aesebu_format_info;
1731 snd_control.get = snd_asihpi_aesebu_rx_format_get;
1732 snd_control.put = snd_asihpi_aesebu_rx_format_put;
1733
1734
1735 if (ctl_add(card, &snd_control, asihpi) < 0)
1736 return -EINVAL;
1737
1738 asihpi_ctl_init(&snd_control, hpi_ctl, "Status");
1739 snd_control.access =
1740 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1741 snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1742 snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1743
1744 return ctl_add(card, &snd_control, asihpi);
1745 }
1746
1747 static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1748 struct snd_ctl_elem_value *ucontrol) {
1749 return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1750 hpi_aesebu_transmitter_get_format);
1751 }
1752
1753 static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1754 struct snd_ctl_elem_value *ucontrol) {
1755 return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1756 hpi_aesebu_transmitter_set_format);
1757 }
1758
1759
1760 static int snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1761 struct hpi_control *hpi_ctl)
1762 {
1763 struct snd_card *card = asihpi->card;
1764 struct snd_kcontrol_new snd_control;
1765
1766 asihpi_ctl_init(&snd_control, hpi_ctl, "Format");
1767 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1768 snd_control.info = snd_asihpi_aesebu_format_info;
1769 snd_control.get = snd_asihpi_aesebu_tx_format_get;
1770 snd_control.put = snd_asihpi_aesebu_tx_format_put;
1771
1772 return ctl_add(card, &snd_control, asihpi);
1773 }
1774
1775
1776
1777
1778
1779
1780
1781 static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1782 struct snd_ctl_elem_info *uinfo)
1783 {
1784 u32 h_control = kcontrol->private_value;
1785 u16 err;
1786 short idx;
1787 u16 gain_range[3];
1788
1789 for (idx = 0; idx < 3; idx++) {
1790 err = hpi_tuner_query_gain(h_control,
1791 idx, &gain_range[idx]);
1792 if (err != 0)
1793 return err;
1794 }
1795
1796 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1797 uinfo->count = 1;
1798 uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1799 uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1800 uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1801 return 0;
1802 }
1803
1804 static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1805 struct snd_ctl_elem_value *ucontrol)
1806 {
1807
1808
1809
1810 u32 h_control = kcontrol->private_value;
1811 short gain;
1812
1813 hpi_handle_error(hpi_tuner_get_gain(h_control, &gain));
1814 ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1815
1816 return 0;
1817 }
1818
1819 static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1820 struct snd_ctl_elem_value *ucontrol)
1821 {
1822
1823
1824
1825 u32 h_control = kcontrol->private_value;
1826 short gain;
1827
1828 gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1829 hpi_handle_error(hpi_tuner_set_gain(h_control, gain));
1830
1831 return 1;
1832 }
1833
1834
1835
1836 static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1837 u16 *band_list, u32 len) {
1838 u32 h_control = kcontrol->private_value;
1839 u16 err = 0;
1840 u32 i;
1841
1842 for (i = 0; i < len; i++) {
1843 err = hpi_tuner_query_band(
1844 h_control, i, &band_list[i]);
1845 if (err != 0)
1846 break;
1847 }
1848
1849 if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1850 return -EIO;
1851
1852 return i;
1853 }
1854
1855 static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1856 struct snd_ctl_elem_info *uinfo)
1857 {
1858 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1859 int num_bands = 0;
1860
1861 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1862 HPI_TUNER_BAND_LAST);
1863
1864 if (num_bands < 0)
1865 return num_bands;
1866
1867 return snd_ctl_enum_info(uinfo, 1, num_bands, asihpi_tuner_band_names);
1868 }
1869
1870 static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1871 struct snd_ctl_elem_value *ucontrol)
1872 {
1873 u32 h_control = kcontrol->private_value;
1874
1875
1876
1877 u16 band, idx;
1878 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1879 __always_unused u32 num_bands;
1880
1881 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1882 HPI_TUNER_BAND_LAST);
1883
1884 hpi_handle_error(hpi_tuner_get_band(h_control, &band));
1885
1886 ucontrol->value.enumerated.item[0] = -1;
1887 for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1888 if (tuner_bands[idx] == band) {
1889 ucontrol->value.enumerated.item[0] = idx;
1890 break;
1891 }
1892
1893 return 0;
1894 }
1895
1896 static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1897 struct snd_ctl_elem_value *ucontrol)
1898 {
1899
1900
1901
1902 u32 h_control = kcontrol->private_value;
1903 unsigned int idx;
1904 u16 band;
1905 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1906 __always_unused u32 num_bands;
1907
1908 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1909 HPI_TUNER_BAND_LAST);
1910
1911 idx = ucontrol->value.enumerated.item[0];
1912 if (idx >= ARRAY_SIZE(tuner_bands))
1913 idx = ARRAY_SIZE(tuner_bands) - 1;
1914 band = tuner_bands[idx];
1915 hpi_handle_error(hpi_tuner_set_band(h_control, band));
1916
1917 return 1;
1918 }
1919
1920
1921
1922 static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1923 struct snd_ctl_elem_info *uinfo)
1924 {
1925 u32 h_control = kcontrol->private_value;
1926 u16 err;
1927 u16 tuner_bands[HPI_TUNER_BAND_LAST];
1928 u16 num_bands = 0, band_iter, idx;
1929 u32 freq_range[3], temp_freq_range[3];
1930
1931 num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1932 HPI_TUNER_BAND_LAST);
1933
1934 freq_range[0] = INT_MAX;
1935 freq_range[1] = 0;
1936 freq_range[2] = INT_MAX;
1937
1938 for (band_iter = 0; band_iter < num_bands; band_iter++) {
1939 for (idx = 0; idx < 3; idx++) {
1940 err = hpi_tuner_query_frequency(h_control,
1941 idx, tuner_bands[band_iter],
1942 &temp_freq_range[idx]);
1943 if (err != 0)
1944 return err;
1945 }
1946
1947
1948 if (temp_freq_range[2] <= 0)
1949 continue;
1950
1951 if (temp_freq_range[0] < freq_range[0])
1952 freq_range[0] = temp_freq_range[0];
1953 if (temp_freq_range[1] > freq_range[1])
1954 freq_range[1] = temp_freq_range[1];
1955 if (temp_freq_range[2] < freq_range[2])
1956 freq_range[2] = temp_freq_range[2];
1957 }
1958
1959 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1960 uinfo->count = 1;
1961 uinfo->value.integer.min = ((int)freq_range[0]);
1962 uinfo->value.integer.max = ((int)freq_range[1]);
1963 uinfo->value.integer.step = ((int)freq_range[2]);
1964 return 0;
1965 }
1966
1967 static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1968 struct snd_ctl_elem_value *ucontrol)
1969 {
1970 u32 h_control = kcontrol->private_value;
1971 u32 freq;
1972
1973 hpi_handle_error(hpi_tuner_get_frequency(h_control, &freq));
1974 ucontrol->value.integer.value[0] = freq;
1975
1976 return 0;
1977 }
1978
1979 static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
1980 struct snd_ctl_elem_value *ucontrol)
1981 {
1982 u32 h_control = kcontrol->private_value;
1983 u32 freq;
1984
1985 freq = ucontrol->value.integer.value[0];
1986 hpi_handle_error(hpi_tuner_set_frequency(h_control, freq));
1987
1988 return 1;
1989 }
1990
1991
1992 static int snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
1993 struct hpi_control *hpi_ctl)
1994 {
1995 struct snd_card *card = asihpi->card;
1996 struct snd_kcontrol_new snd_control;
1997
1998 snd_control.private_value = hpi_ctl->h_control;
1999 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2000
2001 if (!hpi_tuner_get_gain(hpi_ctl->h_control, NULL)) {
2002 asihpi_ctl_init(&snd_control, hpi_ctl, "Gain");
2003 snd_control.info = snd_asihpi_tuner_gain_info;
2004 snd_control.get = snd_asihpi_tuner_gain_get;
2005 snd_control.put = snd_asihpi_tuner_gain_put;
2006
2007 if (ctl_add(card, &snd_control, asihpi) < 0)
2008 return -EINVAL;
2009 }
2010
2011 asihpi_ctl_init(&snd_control, hpi_ctl, "Band");
2012 snd_control.info = snd_asihpi_tuner_band_info;
2013 snd_control.get = snd_asihpi_tuner_band_get;
2014 snd_control.put = snd_asihpi_tuner_band_put;
2015
2016 if (ctl_add(card, &snd_control, asihpi) < 0)
2017 return -EINVAL;
2018
2019 asihpi_ctl_init(&snd_control, hpi_ctl, "Freq");
2020 snd_control.info = snd_asihpi_tuner_freq_info;
2021 snd_control.get = snd_asihpi_tuner_freq_get;
2022 snd_control.put = snd_asihpi_tuner_freq_put;
2023
2024 return ctl_add(card, &snd_control, asihpi);
2025 }
2026
2027
2028
2029
2030 static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_info *uinfo)
2032 {
2033 u32 h_control = kcontrol->private_value;
2034 u32 count;
2035 u16 err;
2036 err = hpi_meter_query_channels(h_control, &count);
2037 if (err)
2038 count = HPI_MAX_CHANNELS;
2039
2040 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2041 uinfo->count = count;
2042 uinfo->value.integer.min = 0;
2043 uinfo->value.integer.max = 0x7FFFFFFF;
2044 return 0;
2045 }
2046
2047
2048 static const int log2lin[] = {
2049 0x7FFFFFFF,
2050 679093956,
2051 214748365,
2052 67909396,
2053 21474837,
2054 6790940,
2055 2147484,
2056 679094,
2057 214748,
2058 67909,
2059 21475,
2060 6791,
2061 2147,
2062 679,
2063 214,
2064 68,
2065 21,
2066 7,
2067 2
2068 };
2069
2070 static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2071 struct snd_ctl_elem_value *ucontrol)
2072 {
2073 u32 h_control = kcontrol->private_value;
2074 short an_gain_mB[HPI_MAX_CHANNELS], i;
2075 u16 err;
2076
2077 err = hpi_meter_get_peak(h_control, an_gain_mB);
2078
2079 for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2080 if (err) {
2081 ucontrol->value.integer.value[i] = 0;
2082 } else if (an_gain_mB[i] >= 0) {
2083 ucontrol->value.integer.value[i] =
2084 an_gain_mB[i] << 16;
2085 } else {
2086
2087
2088
2089 ucontrol->value.integer.value[i] =
2090 log2lin[an_gain_mB[i] / -1000];
2091 }
2092 }
2093 return 0;
2094 }
2095
2096 static int snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2097 struct hpi_control *hpi_ctl, int subidx)
2098 {
2099 struct snd_card *card = asihpi->card;
2100 struct snd_kcontrol_new snd_control;
2101
2102 asihpi_ctl_init(&snd_control, hpi_ctl, "Meter");
2103 snd_control.access =
2104 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2105 snd_control.info = snd_asihpi_meter_info;
2106 snd_control.get = snd_asihpi_meter_get;
2107
2108 snd_control.index = subidx;
2109
2110 return ctl_add(card, &snd_control, asihpi);
2111 }
2112
2113
2114
2115
2116 static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2117 {
2118 u32 h_control = snd_control->private_value;
2119 struct hpi_control hpi_ctl;
2120 int s, err;
2121 for (s = 0; s < 32; s++) {
2122 err = hpi_multiplexer_query_source(h_control, s,
2123 &hpi_ctl.
2124 src_node_type,
2125 &hpi_ctl.
2126 src_node_index);
2127 if (err)
2128 break;
2129 }
2130 return s;
2131 }
2132
2133 static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2134 struct snd_ctl_elem_info *uinfo)
2135 {
2136 u16 src_node_type, src_node_index;
2137 u32 h_control = kcontrol->private_value;
2138
2139 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2140 uinfo->count = 1;
2141 uinfo->value.enumerated.items =
2142 snd_card_asihpi_mux_count_sources(kcontrol);
2143
2144 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2145 uinfo->value.enumerated.item =
2146 uinfo->value.enumerated.items - 1;
2147
2148 hpi_multiplexer_query_source(h_control,
2149 uinfo->value.enumerated.item,
2150 &src_node_type, &src_node_index);
2151
2152 sprintf(uinfo->value.enumerated.name, "%s %d",
2153 asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2154 src_node_index);
2155 return 0;
2156 }
2157
2158 static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2159 struct snd_ctl_elem_value *ucontrol)
2160 {
2161 u32 h_control = kcontrol->private_value;
2162 u16 source_type, source_index;
2163 u16 src_node_type, src_node_index;
2164 int s;
2165
2166 hpi_handle_error(hpi_multiplexer_get_source(h_control,
2167 &source_type, &source_index));
2168
2169 for (s = 0; s < 256; s++) {
2170 if (hpi_multiplexer_query_source(h_control, s,
2171 &src_node_type, &src_node_index))
2172 break;
2173
2174 if ((source_type == src_node_type)
2175 && (source_index == src_node_index)) {
2176 ucontrol->value.enumerated.item[0] = s;
2177 return 0;
2178 }
2179 }
2180 snd_printd(KERN_WARNING
2181 "Control %x failed to match mux source %hu %hu\n",
2182 h_control, source_type, source_index);
2183 ucontrol->value.enumerated.item[0] = 0;
2184 return 0;
2185 }
2186
2187 static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2188 struct snd_ctl_elem_value *ucontrol)
2189 {
2190 int change;
2191 u32 h_control = kcontrol->private_value;
2192 u16 source_type, source_index;
2193 u16 e;
2194
2195 change = 1;
2196
2197 e = hpi_multiplexer_query_source(h_control,
2198 ucontrol->value.enumerated.item[0],
2199 &source_type, &source_index);
2200 if (!e)
2201 hpi_handle_error(
2202 hpi_multiplexer_set_source(h_control,
2203 source_type, source_index));
2204 return change;
2205 }
2206
2207
2208 static int snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2209 struct hpi_control *hpi_ctl)
2210 {
2211 struct snd_card *card = asihpi->card;
2212 struct snd_kcontrol_new snd_control;
2213
2214 asihpi_ctl_init(&snd_control, hpi_ctl, "Route");
2215 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2216 snd_control.info = snd_asihpi_mux_info;
2217 snd_control.get = snd_asihpi_mux_get;
2218 snd_control.put = snd_asihpi_mux_put;
2219
2220 return ctl_add(card, &snd_control, asihpi);
2221
2222 }
2223
2224
2225
2226
2227 static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2228 struct snd_ctl_elem_info *uinfo)
2229 {
2230 static const char * const mode_names[HPI_CHANNEL_MODE_LAST + 1] = {
2231 "invalid",
2232 "Normal", "Swap",
2233 "From Left", "From Right",
2234 "To Left", "To Right"
2235 };
2236
2237 u32 h_control = kcontrol->private_value;
2238 u16 mode;
2239 int i;
2240 const char *mapped_names[6];
2241 int valid_modes = 0;
2242
2243
2244
2245
2246 for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2247 if (!hpi_channel_mode_query_mode(
2248 h_control, i, &mode)) {
2249 mapped_names[valid_modes] = mode_names[mode];
2250 valid_modes++;
2251 }
2252
2253 if (!valid_modes)
2254 return -EINVAL;
2255
2256 return snd_ctl_enum_info(uinfo, 1, valid_modes, mapped_names);
2257 }
2258
2259 static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2260 struct snd_ctl_elem_value *ucontrol)
2261 {
2262 u32 h_control = kcontrol->private_value;
2263 u16 mode;
2264
2265 if (hpi_channel_mode_get(h_control, &mode))
2266 mode = 1;
2267
2268 ucontrol->value.enumerated.item[0] = mode - 1;
2269
2270 return 0;
2271 }
2272
2273 static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2274 struct snd_ctl_elem_value *ucontrol)
2275 {
2276 int change;
2277 u32 h_control = kcontrol->private_value;
2278
2279 change = 1;
2280
2281 hpi_handle_error(hpi_channel_mode_set(h_control,
2282 ucontrol->value.enumerated.item[0] + 1));
2283 return change;
2284 }
2285
2286
2287 static int snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2288 struct hpi_control *hpi_ctl)
2289 {
2290 struct snd_card *card = asihpi->card;
2291 struct snd_kcontrol_new snd_control;
2292
2293 asihpi_ctl_init(&snd_control, hpi_ctl, "Mode");
2294 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2295 snd_control.info = snd_asihpi_cmode_info;
2296 snd_control.get = snd_asihpi_cmode_get;
2297 snd_control.put = snd_asihpi_cmode_put;
2298
2299 return ctl_add(card, &snd_control, asihpi);
2300 }
2301
2302
2303
2304
2305 static const char * const sampleclock_sources[] = {
2306 "N/A", "Local PLL", "Digital Sync", "Word External", "Word Header",
2307 "SMPTE", "Digital1", "Auto", "Network", "Invalid",
2308 "Prev Module", "BLU-Link",
2309 "Digital2", "Digital3", "Digital4", "Digital5",
2310 "Digital6", "Digital7", "Digital8"};
2311
2312
2313 compile_time_assert(
2314 (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES),
2315 assert_sampleclock_sources_size);
2316
2317 static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2318 struct snd_ctl_elem_info *uinfo)
2319 {
2320 struct snd_card_asihpi *asihpi =
2321 (struct snd_card_asihpi *)(kcontrol->private_data);
2322 struct clk_cache *clkcache = &asihpi->cc;
2323 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2324 uinfo->count = 1;
2325 uinfo->value.enumerated.items = clkcache->count;
2326
2327 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2328 uinfo->value.enumerated.item =
2329 uinfo->value.enumerated.items - 1;
2330
2331 strcpy(uinfo->value.enumerated.name,
2332 clkcache->s[uinfo->value.enumerated.item].name);
2333 return 0;
2334 }
2335
2336 static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2337 struct snd_ctl_elem_value *ucontrol)
2338 {
2339 struct snd_card_asihpi *asihpi =
2340 (struct snd_card_asihpi *)(kcontrol->private_data);
2341 struct clk_cache *clkcache = &asihpi->cc;
2342 u32 h_control = kcontrol->private_value;
2343 u16 source, srcindex = 0;
2344 int i;
2345
2346 ucontrol->value.enumerated.item[0] = 0;
2347 if (hpi_sample_clock_get_source(h_control, &source))
2348 source = 0;
2349
2350 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2351 if (hpi_sample_clock_get_source_index(h_control, &srcindex))
2352 srcindex = 0;
2353
2354 for (i = 0; i < clkcache->count; i++)
2355 if ((clkcache->s[i].source == source) &&
2356 (clkcache->s[i].index == srcindex))
2357 break;
2358
2359 ucontrol->value.enumerated.item[0] = i;
2360
2361 return 0;
2362 }
2363
2364 static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2365 struct snd_ctl_elem_value *ucontrol)
2366 {
2367 struct snd_card_asihpi *asihpi =
2368 (struct snd_card_asihpi *)(kcontrol->private_data);
2369 struct clk_cache *clkcache = &asihpi->cc;
2370 unsigned int item;
2371 int change;
2372 u32 h_control = kcontrol->private_value;
2373
2374 change = 1;
2375 item = ucontrol->value.enumerated.item[0];
2376 if (item >= clkcache->count)
2377 item = clkcache->count-1;
2378
2379 hpi_handle_error(hpi_sample_clock_set_source(
2380 h_control, clkcache->s[item].source));
2381
2382 if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2383 hpi_handle_error(hpi_sample_clock_set_source_index(
2384 h_control, clkcache->s[item].index));
2385 return change;
2386 }
2387
2388
2389
2390
2391
2392 static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2393 struct snd_ctl_elem_info *uinfo)
2394 {
2395 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2396 uinfo->count = 1;
2397 uinfo->value.integer.min = 8000;
2398 uinfo->value.integer.max = 192000;
2399 uinfo->value.integer.step = 100;
2400
2401 return 0;
2402 }
2403
2404 static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2405 struct snd_ctl_elem_value *ucontrol)
2406 {
2407 u32 h_control = kcontrol->private_value;
2408 u32 rate;
2409 u16 e;
2410
2411 e = hpi_sample_clock_get_local_rate(h_control, &rate);
2412 if (!e)
2413 ucontrol->value.integer.value[0] = rate;
2414 else
2415 ucontrol->value.integer.value[0] = 0;
2416 return 0;
2417 }
2418
2419 static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2420 struct snd_ctl_elem_value *ucontrol)
2421 {
2422 int change;
2423 u32 h_control = kcontrol->private_value;
2424
2425
2426
2427
2428 change = 1;
2429 hpi_handle_error(hpi_sample_clock_set_local_rate(h_control,
2430 ucontrol->value.integer.value[0]));
2431 return change;
2432 }
2433
2434 static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2435 struct snd_ctl_elem_info *uinfo)
2436 {
2437 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2438 uinfo->count = 1;
2439 uinfo->value.integer.min = 8000;
2440 uinfo->value.integer.max = 192000;
2441 uinfo->value.integer.step = 100;
2442
2443 return 0;
2444 }
2445
2446 static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2447 struct snd_ctl_elem_value *ucontrol)
2448 {
2449 u32 h_control = kcontrol->private_value;
2450 u32 rate;
2451 u16 e;
2452
2453 e = hpi_sample_clock_get_sample_rate(h_control, &rate);
2454 if (!e)
2455 ucontrol->value.integer.value[0] = rate;
2456 else
2457 ucontrol->value.integer.value[0] = 0;
2458 return 0;
2459 }
2460
2461 static int snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2462 struct hpi_control *hpi_ctl)
2463 {
2464 struct snd_card *card;
2465 struct snd_kcontrol_new snd_control;
2466
2467 struct clk_cache *clkcache;
2468 u32 hSC = hpi_ctl->h_control;
2469 int has_aes_in = 0;
2470 int i, j;
2471 u16 source;
2472
2473 if (snd_BUG_ON(!asihpi))
2474 return -EINVAL;
2475 card = asihpi->card;
2476 clkcache = &asihpi->cc;
2477 snd_control.private_value = hpi_ctl->h_control;
2478
2479 clkcache->has_local = 0;
2480
2481 for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2482 if (hpi_sample_clock_query_source(hSC,
2483 i, &source))
2484 break;
2485 clkcache->s[i].source = source;
2486 clkcache->s[i].index = 0;
2487 clkcache->s[i].name = sampleclock_sources[source];
2488 if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2489 has_aes_in = 1;
2490 if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2491 clkcache->has_local = 1;
2492 }
2493 if (has_aes_in)
2494
2495 for (j = 1; j < 8; j++) {
2496 if (hpi_sample_clock_query_source_index(hSC,
2497 j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2498 &source))
2499 break;
2500 clkcache->s[i].source =
2501 HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2502 clkcache->s[i].index = j;
2503 clkcache->s[i].name = sampleclock_sources[
2504 j+HPI_SAMPLECLOCK_SOURCE_LAST];
2505 i++;
2506 }
2507 clkcache->count = i;
2508
2509 asihpi_ctl_init(&snd_control, hpi_ctl, "Source");
2510 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2511 snd_control.info = snd_asihpi_clksrc_info;
2512 snd_control.get = snd_asihpi_clksrc_get;
2513 snd_control.put = snd_asihpi_clksrc_put;
2514 if (ctl_add(card, &snd_control, asihpi) < 0)
2515 return -EINVAL;
2516
2517
2518 if (clkcache->has_local) {
2519 asihpi_ctl_init(&snd_control, hpi_ctl, "Localrate");
2520 snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2521 snd_control.info = snd_asihpi_clklocal_info;
2522 snd_control.get = snd_asihpi_clklocal_get;
2523 snd_control.put = snd_asihpi_clklocal_put;
2524
2525
2526 if (ctl_add(card, &snd_control, asihpi) < 0)
2527 return -EINVAL;
2528 }
2529
2530 asihpi_ctl_init(&snd_control, hpi_ctl, "Rate");
2531 snd_control.access =
2532 SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2533 snd_control.info = snd_asihpi_clkrate_info;
2534 snd_control.get = snd_asihpi_clkrate_get;
2535
2536 return ctl_add(card, &snd_control, asihpi);
2537 }
2538
2539
2540
2541
2542 static int snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2543 {
2544 struct snd_card *card;
2545 unsigned int idx = 0;
2546 unsigned int subindex = 0;
2547 int err;
2548 struct hpi_control hpi_ctl, prev_ctl;
2549
2550 if (snd_BUG_ON(!asihpi))
2551 return -EINVAL;
2552 card = asihpi->card;
2553 strcpy(card->mixername, "Asihpi Mixer");
2554
2555 err =
2556 hpi_mixer_open(asihpi->hpi->adapter->index,
2557 &asihpi->h_mixer);
2558 hpi_handle_error(err);
2559 if (err)
2560 return -err;
2561
2562 memset(&prev_ctl, 0, sizeof(prev_ctl));
2563 prev_ctl.control_type = -1;
2564
2565 for (idx = 0; idx < 2000; idx++) {
2566 err = hpi_mixer_get_control_by_index(
2567 asihpi->h_mixer,
2568 idx,
2569 &hpi_ctl.src_node_type,
2570 &hpi_ctl.src_node_index,
2571 &hpi_ctl.dst_node_type,
2572 &hpi_ctl.dst_node_index,
2573 &hpi_ctl.control_type,
2574 &hpi_ctl.h_control);
2575 if (err) {
2576 if (err == HPI_ERROR_CONTROL_DISABLED) {
2577 if (mixer_dump)
2578 dev_info(&asihpi->pci->dev,
2579 "Disabled HPI Control(%d)\n",
2580 idx);
2581 continue;
2582 } else
2583 break;
2584
2585 }
2586
2587 hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2588 hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2589
2590
2591
2592
2593
2594 if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2595 (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2596 (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2597 (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2598 (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2599 subindex++;
2600 else
2601 subindex = 0;
2602
2603 prev_ctl = hpi_ctl;
2604
2605 switch (hpi_ctl.control_type) {
2606 case HPI_CONTROL_VOLUME:
2607 err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2608 break;
2609 case HPI_CONTROL_LEVEL:
2610 err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2611 break;
2612 case HPI_CONTROL_MULTIPLEXER:
2613 err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2614 break;
2615 case HPI_CONTROL_CHANNEL_MODE:
2616 err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2617 break;
2618 case HPI_CONTROL_METER:
2619 err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2620 break;
2621 case HPI_CONTROL_SAMPLECLOCK:
2622 err = snd_asihpi_sampleclock_add(
2623 asihpi, &hpi_ctl);
2624 break;
2625 case HPI_CONTROL_CONNECTION:
2626 continue;
2627 case HPI_CONTROL_TUNER:
2628 err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2629 break;
2630 case HPI_CONTROL_AESEBU_TRANSMITTER:
2631 err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2632 break;
2633 case HPI_CONTROL_AESEBU_RECEIVER:
2634 err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2635 break;
2636 case HPI_CONTROL_VOX:
2637 case HPI_CONTROL_BITSTREAM:
2638 case HPI_CONTROL_MICROPHONE:
2639 case HPI_CONTROL_PARAMETRIC_EQ:
2640 case HPI_CONTROL_COMPANDER:
2641 default:
2642 if (mixer_dump)
2643 dev_info(&asihpi->pci->dev,
2644 "Untranslated HPI Control (%d) %d %d %d %d %d\n",
2645 idx,
2646 hpi_ctl.control_type,
2647 hpi_ctl.src_node_type,
2648 hpi_ctl.src_node_index,
2649 hpi_ctl.dst_node_type,
2650 hpi_ctl.dst_node_index);
2651 continue;
2652 }
2653 if (err < 0)
2654 return err;
2655 }
2656 if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2657 hpi_handle_error(err);
2658
2659 dev_info(&asihpi->pci->dev, "%d mixer controls found\n", idx);
2660
2661 return 0;
2662 }
2663
2664
2665
2666
2667
2668 static void
2669 snd_asihpi_proc_read(struct snd_info_entry *entry,
2670 struct snd_info_buffer *buffer)
2671 {
2672 struct snd_card_asihpi *asihpi = entry->private_data;
2673 u32 h_control;
2674 u32 rate = 0;
2675 u16 source = 0;
2676
2677 u16 num_outstreams;
2678 u16 num_instreams;
2679 u16 version;
2680 u32 serial_number;
2681 u16 type;
2682
2683 int err;
2684
2685 snd_iprintf(buffer, "ASIHPI driver proc file\n");
2686
2687 hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index,
2688 &num_outstreams, &num_instreams,
2689 &version, &serial_number, &type));
2690
2691 snd_iprintf(buffer,
2692 "Adapter type ASI%4X\nHardware Index %d\n"
2693 "%d outstreams\n%d instreams\n",
2694 type, asihpi->hpi->adapter->index,
2695 num_outstreams, num_instreams);
2696
2697 snd_iprintf(buffer,
2698 "Serial#%d\nHardware version %c%d\nDSP code version %03d\n",
2699 serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7,
2700 ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2701
2702 err = hpi_mixer_get_control(asihpi->h_mixer,
2703 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2704 HPI_CONTROL_SAMPLECLOCK, &h_control);
2705
2706 if (!err) {
2707 err = hpi_sample_clock_get_sample_rate(h_control, &rate);
2708 err += hpi_sample_clock_get_source(h_control, &source);
2709
2710 if (!err)
2711 snd_iprintf(buffer, "Sample Clock %dHz, source %s\n",
2712 rate, sampleclock_sources[source]);
2713 }
2714 }
2715
2716 static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2717 {
2718 snd_card_ro_proc_new(asihpi->card, "info", asihpi,
2719 snd_asihpi_proc_read);
2720 }
2721
2722
2723
2724
2725
2726 static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2727 {
2728 if (enable_hpi_hwdep)
2729 return 0;
2730 else
2731 return -ENODEV;
2732
2733 }
2734
2735 static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2736 {
2737 if (enable_hpi_hwdep)
2738 return asihpi_hpi_release(file);
2739 else
2740 return -ENODEV;
2741 }
2742
2743 static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2744 unsigned int cmd, unsigned long arg)
2745 {
2746 if (enable_hpi_hwdep)
2747 return asihpi_hpi_ioctl(file, cmd, arg);
2748 else
2749 return -ENODEV;
2750 }
2751
2752
2753
2754
2755
2756 static int snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi, int device)
2757 {
2758 struct snd_hwdep *hw;
2759 int err;
2760
2761 err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2762 if (err < 0)
2763 return err;
2764 strcpy(hw->name, "asihpi (HPI)");
2765 hw->iface = SNDRV_HWDEP_IFACE_LAST;
2766 hw->ops.open = snd_asihpi_hpi_open;
2767 hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2768 hw->ops.release = snd_asihpi_hpi_release;
2769 hw->private_data = asihpi;
2770 return 0;
2771 }
2772
2773
2774
2775
2776 static int snd_asihpi_probe(struct pci_dev *pci_dev,
2777 const struct pci_device_id *pci_id)
2778 {
2779 int err;
2780 struct hpi_adapter *hpi;
2781 struct snd_card *card;
2782 struct snd_card_asihpi *asihpi;
2783
2784 u32 h_control;
2785 u32 h_stream;
2786 u32 adapter_index;
2787
2788 static int dev;
2789 if (dev >= SNDRV_CARDS)
2790 return -ENODEV;
2791
2792
2793 if (!enable[dev]) {
2794 dev++;
2795 return -ENOENT;
2796 }
2797
2798
2799 err = asihpi_adapter_probe(pci_dev, pci_id);
2800 if (err < 0)
2801 return err;
2802
2803 hpi = pci_get_drvdata(pci_dev);
2804 adapter_index = hpi->adapter->index;
2805
2806 err = snd_card_new(&pci_dev->dev, adapter_index, id[adapter_index],
2807 THIS_MODULE, sizeof(struct snd_card_asihpi), &card);
2808 if (err < 0) {
2809
2810 err = snd_card_new(&pci_dev->dev, index[dev], id[dev],
2811 THIS_MODULE, sizeof(struct snd_card_asihpi),
2812 &card);
2813 if (err < 0)
2814 return err;
2815 dev_warn(&pci_dev->dev, "Adapter index %d->ALSA index %d\n",
2816 adapter_index, card->number);
2817 }
2818
2819 asihpi = card->private_data;
2820 asihpi->card = card;
2821 asihpi->pci = pci_dev;
2822 asihpi->hpi = hpi;
2823 hpi->snd_card = card;
2824
2825 err = hpi_adapter_get_property(adapter_index,
2826 HPI_ADAPTER_PROPERTY_CAPS1,
2827 NULL, &asihpi->support_grouping);
2828 if (err)
2829 asihpi->support_grouping = 0;
2830
2831 err = hpi_adapter_get_property(adapter_index,
2832 HPI_ADAPTER_PROPERTY_CAPS2,
2833 &asihpi->support_mrx, NULL);
2834 if (err)
2835 asihpi->support_mrx = 0;
2836
2837 err = hpi_adapter_get_property(adapter_index,
2838 HPI_ADAPTER_PROPERTY_INTERVAL,
2839 NULL, &asihpi->update_interval_frames);
2840 if (err)
2841 asihpi->update_interval_frames = 512;
2842
2843 if (hpi->interrupt_mode) {
2844 asihpi->pcm_start = snd_card_asihpi_pcm_int_start;
2845 asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop;
2846 hpi->interrupt_callback = snd_card_asihpi_isr;
2847 } else {
2848 asihpi->pcm_start = snd_card_asihpi_pcm_timer_start;
2849 asihpi->pcm_stop = snd_card_asihpi_pcm_timer_stop;
2850 }
2851
2852 hpi_handle_error(hpi_instream_open(adapter_index,
2853 0, &h_stream));
2854
2855 err = hpi_instream_host_buffer_free(h_stream);
2856 asihpi->can_dma = (!err);
2857
2858 hpi_handle_error(hpi_instream_close(h_stream));
2859
2860 if (!asihpi->can_dma)
2861 asihpi->update_interval_frames *= 2;
2862
2863 err = hpi_adapter_get_property(adapter_index,
2864 HPI_ADAPTER_PROPERTY_CURCHANNELS,
2865 &asihpi->in_max_chans, &asihpi->out_max_chans);
2866 if (err) {
2867 asihpi->in_max_chans = 2;
2868 asihpi->out_max_chans = 2;
2869 }
2870
2871 if (asihpi->out_max_chans > 2) {
2872 asihpi->out_min_chans = asihpi->out_max_chans;
2873 asihpi->in_min_chans = asihpi->in_max_chans;
2874 asihpi->support_grouping = 0;
2875 } else {
2876 asihpi->out_min_chans = 1;
2877 asihpi->in_min_chans = 1;
2878 }
2879
2880 dev_info(&pci_dev->dev, "Has dma:%d, grouping:%d, mrx:%d, uif:%d\n",
2881 asihpi->can_dma,
2882 asihpi->support_grouping,
2883 asihpi->support_mrx,
2884 asihpi->update_interval_frames
2885 );
2886
2887 err = snd_card_asihpi_pcm_new(asihpi, 0);
2888 if (err < 0) {
2889 dev_err(&pci_dev->dev, "pcm_new failed\n");
2890 goto __nodev;
2891 }
2892 err = snd_card_asihpi_mixer_new(asihpi);
2893 if (err < 0) {
2894 dev_err(&pci_dev->dev, "mixer_new failed\n");
2895 goto __nodev;
2896 }
2897
2898 err = hpi_mixer_get_control(asihpi->h_mixer,
2899 HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2900 HPI_CONTROL_SAMPLECLOCK, &h_control);
2901
2902 if (!err)
2903 err = hpi_sample_clock_set_local_rate(
2904 h_control, adapter_fs);
2905
2906 snd_asihpi_proc_init(asihpi);
2907
2908
2909
2910 snd_asihpi_hpi_new(asihpi, 0);
2911
2912 strcpy(card->driver, "ASIHPI");
2913
2914 sprintf(card->shortname, "AudioScience ASI%4X",
2915 asihpi->hpi->adapter->type);
2916 sprintf(card->longname, "%s %i",
2917 card->shortname, adapter_index);
2918 err = snd_card_register(card);
2919
2920 if (!err) {
2921 dev++;
2922 return 0;
2923 }
2924 __nodev:
2925 snd_card_free(card);
2926 dev_err(&pci_dev->dev, "snd_asihpi_probe error %d\n", err);
2927 return err;
2928
2929 }
2930
2931 static void snd_asihpi_remove(struct pci_dev *pci_dev)
2932 {
2933 struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
2934
2935
2936 if (hpi->interrupt_mode) {
2937 hpi->interrupt_callback = NULL;
2938 hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index,
2939 HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
2940 }
2941
2942 snd_card_free(hpi->snd_card);
2943 hpi->snd_card = NULL;
2944 asihpi_adapter_remove(pci_dev);
2945 }
2946
2947 static const struct pci_device_id asihpi_pci_tbl[] = {
2948 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2949 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2950 (kernel_ulong_t)HPI_6205},
2951 {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2952 HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2953 (kernel_ulong_t)HPI_6000},
2954 {0,}
2955 };
2956 MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2957
2958 static struct pci_driver driver = {
2959 .name = KBUILD_MODNAME,
2960 .id_table = asihpi_pci_tbl,
2961 .probe = snd_asihpi_probe,
2962 .remove = snd_asihpi_remove,
2963 };
2964
2965 static int __init snd_asihpi_init(void)
2966 {
2967 asihpi_init();
2968 return pci_register_driver(&driver);
2969 }
2970
2971 static void __exit snd_asihpi_exit(void)
2972 {
2973
2974 pci_unregister_driver(&driver);
2975 asihpi_exit();
2976 }
2977
2978 module_init(snd_asihpi_init)
2979 module_exit(snd_asihpi_exit)
2980