linux/sound/pci/asihpi/asihpi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *  Asihpi soundcard
   4 *  Copyright (c) by AudioScience Inc <support@audioscience.com>
   5 *
   6 *  The following is not a condition of use, merely a request:
   7 *  If you modify this program, particularly if you fix errors, AudioScience Inc
   8 *  would appreciate it if you grant us the right to use those modifications
   9 *  for any purpose including commercial applications.
  10 */
  11
  12#include "hpi_internal.h"
  13#include "hpi_version.h"
  14#include "hpimsginit.h"
  15#include "hpioctl.h"
  16#include "hpicmn.h"
  17
  18#include <linux/pci.h>
  19#include <linux/init.h>
  20#include <linux/jiffies.h>
  21#include <linux/slab.h>
  22#include <linux/time.h>
  23#include <linux/wait.h>
  24#include <linux/module.h>
  25#include <sound/core.h>
  26#include <sound/control.h>
  27#include <sound/pcm.h>
  28#include <sound/pcm_params.h>
  29#include <sound/info.h>
  30#include <sound/initval.h>
  31#include <sound/tlv.h>
  32#include <sound/hwdep.h>
  33
  34MODULE_LICENSE("GPL");
  35MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
  36MODULE_DESCRIPTION("AudioScience ALSA ASI5xxx ASI6xxx ASI87xx ASI89xx "
  37                        HPI_VER_STRING);
  38
  39#if defined CONFIG_SND_DEBUG_VERBOSE
  40/**
  41 * snd_printddd - very verbose debug printk
  42 * @format: format string
  43 *
  44 * Works like snd_printk() for debugging purposes.
  45 * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set.
  46 * Must set snd module debug parameter to 3 to enable at runtime.
  47 */
  48#define snd_printddd(format, args...) \
  49        __snd_printk(3, __FILE__, __LINE__, format, ##args)
  50#else
  51#define snd_printddd(format, args...) do { } while (0)
  52#endif
  53
  54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* index 0-MAX */
  55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
  56static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
  57static bool enable_hpi_hwdep = 1;
  58
  59module_param_array(index, int, NULL, 0444);
  60MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
  61
  62module_param_array(id, charp, NULL, 0444);
  63MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
  64
  65module_param_array(enable, bool, NULL, 0444);
  66MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
  67
  68module_param(enable_hpi_hwdep, bool, 0644);
  69MODULE_PARM_DESC(enable_hpi_hwdep,
  70                "ALSA enable HPI hwdep for AudioScience soundcard ");
  71
  72/* identify driver */
  73#ifdef KERNEL_ALSA_BUILD
  74static char *build_info = "Built using headers from kernel source";
  75module_param(build_info, charp, 0444);
  76MODULE_PARM_DESC(build_info, "Built using headers from kernel source");
  77#else
  78static char *build_info = "Built within ALSA source";
  79module_param(build_info, charp, 0444);
  80MODULE_PARM_DESC(build_info, "Built within ALSA source");
  81#endif
  82
  83/* set to 1 to dump every control from adapter to log */
  84static const int mixer_dump;
  85
  86#define DEFAULT_SAMPLERATE 44100
  87static int adapter_fs = DEFAULT_SAMPLERATE;
  88
  89/* defaults */
  90#define PERIODS_MIN 2
  91#define PERIOD_BYTES_MIN  2048
  92#define BUFFER_BYTES_MAX (512 * 1024)
  93
  94#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
  95
  96struct clk_source {
  97        int source;
  98        int index;
  99        const char *name;
 100};
 101
 102struct clk_cache {
 103        int count;
 104        int has_local;
 105        struct clk_source s[MAX_CLOCKSOURCES];
 106};
 107
 108/* Per card data */
 109struct snd_card_asihpi {
 110        struct snd_card *card;
 111        struct pci_dev *pci;
 112        struct hpi_adapter *hpi;
 113
 114        /* In low latency mode there is only one stream, a pointer to its
 115         * private data is stored here on trigger and cleared on stop.
 116         * The interrupt handler uses it as a parameter when calling
 117         * snd_card_asihpi_timer_function().
 118         */
 119        struct snd_card_asihpi_pcm *llmode_streampriv;
 120        void (*pcm_start)(struct snd_pcm_substream *substream);
 121        void (*pcm_stop)(struct snd_pcm_substream *substream);
 122
 123        u32 h_mixer;
 124        struct clk_cache cc;
 125
 126        u16 can_dma;
 127        u16 support_grouping;
 128        u16 support_mrx;
 129        u16 update_interval_frames;
 130        u16 in_max_chans;
 131        u16 out_max_chans;
 132        u16 in_min_chans;
 133        u16 out_min_chans;
 134};
 135
 136/* Per stream data */
 137struct snd_card_asihpi_pcm {
 138        struct timer_list timer;
 139        unsigned int respawn_timer;
 140        unsigned int hpi_buffer_attached;
 141        unsigned int buffer_bytes;
 142        unsigned int period_bytes;
 143        unsigned int bytes_per_sec;
 144        unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */
 145        unsigned int pcm_buf_dma_ofs;   /* DMA R/W offset in buffer */
 146        unsigned int pcm_buf_elapsed_dma_ofs;   /* DMA R/W offset in buffer */
 147        unsigned int drained_count;
 148        struct snd_pcm_substream *substream;
 149        u32 h_stream;
 150        struct hpi_format format;
 151};
 152
 153/* universal stream verbs work with out or in stream handles */
 154
 155/* Functions to allow driver to give a buffer to HPI for busmastering */
 156
 157static u16 hpi_stream_host_buffer_attach(
 158        u32 h_stream,   /* handle to outstream. */
 159        u32 size_in_bytes, /* size in bytes of bus mastering buffer */
 160        u32 pci_address
 161)
 162{
 163        struct hpi_message hm;
 164        struct hpi_response hr;
 165        unsigned int obj = hpi_handle_object(h_stream);
 166
 167        if (!h_stream)
 168                return HPI_ERROR_INVALID_OBJ;
 169        hpi_init_message_response(&hm, &hr, obj,
 170                        obj == HPI_OBJ_OSTREAM ?
 171                                HPI_OSTREAM_HOSTBUFFER_ALLOC :
 172                                HPI_ISTREAM_HOSTBUFFER_ALLOC);
 173
 174        hpi_handle_to_indexes(h_stream, &hm.adapter_index,
 175                                &hm.obj_index);
 176
 177        hm.u.d.u.buffer.buffer_size = size_in_bytes;
 178        hm.u.d.u.buffer.pci_address = pci_address;
 179        hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
 180        hpi_send_recv(&hm, &hr);
 181        return hr.error;
 182}
 183
 184static u16 hpi_stream_host_buffer_detach(u32  h_stream)
 185{
 186        struct hpi_message hm;
 187        struct hpi_response hr;
 188        unsigned int obj = hpi_handle_object(h_stream);
 189
 190        if (!h_stream)
 191                return HPI_ERROR_INVALID_OBJ;
 192
 193        hpi_init_message_response(&hm, &hr,  obj,
 194                        obj == HPI_OBJ_OSTREAM ?
 195                                HPI_OSTREAM_HOSTBUFFER_FREE :
 196                                HPI_ISTREAM_HOSTBUFFER_FREE);
 197
 198        hpi_handle_to_indexes(h_stream, &hm.adapter_index,
 199                                &hm.obj_index);
 200        hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
 201        hpi_send_recv(&hm, &hr);
 202        return hr.error;
 203}
 204
 205static inline u16 hpi_stream_start(u32 h_stream)
 206{
 207        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 208                return hpi_outstream_start(h_stream);
 209        else
 210                return hpi_instream_start(h_stream);
 211}
 212
 213static inline u16 hpi_stream_stop(u32 h_stream)
 214{
 215        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 216                return hpi_outstream_stop(h_stream);
 217        else
 218                return hpi_instream_stop(h_stream);
 219}
 220
 221static inline u16 hpi_stream_get_info_ex(
 222    u32 h_stream,
 223    u16        *pw_state,
 224    u32        *pbuffer_size,
 225    u32        *pdata_in_buffer,
 226    u32        *psample_count,
 227    u32        *pauxiliary_data
 228)
 229{
 230        u16 e;
 231        if (hpi_handle_object(h_stream)  ==  HPI_OBJ_OSTREAM)
 232                e = hpi_outstream_get_info_ex(h_stream, pw_state,
 233                                        pbuffer_size, pdata_in_buffer,
 234                                        psample_count, pauxiliary_data);
 235        else
 236                e = hpi_instream_get_info_ex(h_stream, pw_state,
 237                                        pbuffer_size, pdata_in_buffer,
 238                                        psample_count, pauxiliary_data);
 239        return e;
 240}
 241
 242static inline u16 hpi_stream_group_add(
 243                                        u32 h_master,
 244                                        u32 h_stream)
 245{
 246        if (hpi_handle_object(h_master) ==  HPI_OBJ_OSTREAM)
 247                return hpi_outstream_group_add(h_master, h_stream);
 248        else
 249                return hpi_instream_group_add(h_master, h_stream);
 250}
 251
 252static inline u16 hpi_stream_group_reset(u32 h_stream)
 253{
 254        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 255                return hpi_outstream_group_reset(h_stream);
 256        else
 257                return hpi_instream_group_reset(h_stream);
 258}
 259
 260static u16 handle_error(u16 err, int line, char *filename)
 261{
 262        if (err)
 263                printk(KERN_WARNING
 264                        "in file %s, line %d: HPI error %d\n",
 265                        filename, line, err);
 266        return err;
 267}
 268
 269#define hpi_handle_error(x)  handle_error(x, __LINE__, __FILE__)
 270
 271/***************************** GENERAL PCM ****************/
 272
 273static void print_hwparams(struct snd_pcm_substream *substream,
 274                                struct snd_pcm_hw_params *p)
 275{
 276        char name[16];
 277        snd_pcm_debug_name(substream, name, sizeof(name));
 278        snd_printdd("%s HWPARAMS\n", name);
 279        snd_printdd(" samplerate=%dHz channels=%d format=%d subformat=%d\n",
 280                params_rate(p), params_channels(p),
 281                params_format(p), params_subformat(p));
 282        snd_printdd(" buffer=%dB period=%dB period_size=%dB periods=%d\n",
 283                params_buffer_bytes(p), params_period_bytes(p),
 284                params_period_size(p), params_periods(p));
 285        snd_printdd(" buffer_size=%d access=%d data_rate=%dB/s\n",
 286                params_buffer_size(p), params_access(p),
 287                params_rate(p) * params_channels(p) *
 288                snd_pcm_format_width(params_format(p)) / 8);
 289}
 290
 291#define INVALID_FORMAT  (__force snd_pcm_format_t)(-1)
 292
 293static const snd_pcm_format_t hpi_to_alsa_formats[] = {
 294        INVALID_FORMAT,         /* INVALID */
 295        SNDRV_PCM_FORMAT_U8,    /* HPI_FORMAT_PCM8_UNSIGNED        1 */
 296        SNDRV_PCM_FORMAT_S16,   /* HPI_FORMAT_PCM16_SIGNED         2 */
 297        INVALID_FORMAT,         /* HPI_FORMAT_MPEG_L1              3 */
 298        SNDRV_PCM_FORMAT_MPEG,  /* HPI_FORMAT_MPEG_L2              4 */
 299        SNDRV_PCM_FORMAT_MPEG,  /* HPI_FORMAT_MPEG_L3              5 */
 300        INVALID_FORMAT,         /* HPI_FORMAT_DOLBY_AC2            6 */
 301        INVALID_FORMAT,         /* HPI_FORMAT_DOLBY_AC3            7 */
 302        SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN      8 */
 303        INVALID_FORMAT,         /* HPI_FORMAT_AA_TAGIT1_HITS       9 */
 304        INVALID_FORMAT,         /* HPI_FORMAT_AA_TAGIT1_INSERTS   10 */
 305        SNDRV_PCM_FORMAT_S32,   /* HPI_FORMAT_PCM32_SIGNED        11 */
 306        INVALID_FORMAT,         /* HPI_FORMAT_RAW_BITSTREAM       12 */
 307        INVALID_FORMAT,         /* HPI_FORMAT_AA_TAGIT1_HITS_EX1  13 */
 308        SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT         14 */
 309#if 1
 310        /* ALSA can't handle 3 byte sample size together with power-of-2
 311         *  constraint on buffer_bytes, so disable this format
 312         */
 313        INVALID_FORMAT
 314#else
 315        /* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
 316#endif
 317};
 318
 319
 320static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
 321                                           u16 *hpi_format)
 322{
 323        u16 format;
 324
 325        for (format = HPI_FORMAT_PCM8_UNSIGNED;
 326             format <= HPI_FORMAT_PCM24_SIGNED; format++) {
 327                if (hpi_to_alsa_formats[format] == alsa_format) {
 328                        *hpi_format = format;
 329                        return 0;
 330                }
 331        }
 332
 333        snd_printd(KERN_WARNING "failed match for alsa format %d\n",
 334                   alsa_format);
 335        *hpi_format = 0;
 336        return -EINVAL;
 337}
 338
 339static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
 340                                         struct snd_pcm_hardware *pcmhw)
 341{
 342        u16 err;
 343        u32 h_control;
 344        u32 sample_rate;
 345        int idx;
 346        unsigned int rate_min = 200000;
 347        unsigned int rate_max = 0;
 348        unsigned int rates = 0;
 349
 350        if (asihpi->support_mrx) {
 351                rates |= SNDRV_PCM_RATE_CONTINUOUS;
 352                rates |= SNDRV_PCM_RATE_8000_96000;
 353                rate_min = 8000;
 354                rate_max = 100000;
 355        } else {
 356                /* on cards without SRC,
 357                   valid rates are determined by sampleclock */
 358                err = hpi_mixer_get_control(asihpi->h_mixer,
 359                                          HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
 360                                          HPI_CONTROL_SAMPLECLOCK, &h_control);
 361                if (err) {
 362                        dev_err(&asihpi->pci->dev,
 363                                "No local sampleclock, err %d\n", err);
 364                }
 365
 366                for (idx = -1; idx < 100; idx++) {
 367                        if (idx == -1) {
 368                                if (hpi_sample_clock_get_sample_rate(h_control,
 369                                                                &sample_rate))
 370                                        continue;
 371                        } else if (hpi_sample_clock_query_local_rate(h_control,
 372                                                        idx, &sample_rate)) {
 373                                break;
 374                        }
 375
 376                        rate_min = min(rate_min, sample_rate);
 377                        rate_max = max(rate_max, sample_rate);
 378
 379                        switch (sample_rate) {
 380                        case 5512:
 381                                rates |= SNDRV_PCM_RATE_5512;
 382                                break;
 383                        case 8000:
 384                                rates |= SNDRV_PCM_RATE_8000;
 385                                break;
 386                        case 11025:
 387                                rates |= SNDRV_PCM_RATE_11025;
 388                                break;
 389                        case 16000:
 390                                rates |= SNDRV_PCM_RATE_16000;
 391                                break;
 392                        case 22050:
 393                                rates |= SNDRV_PCM_RATE_22050;
 394                                break;
 395                        case 32000:
 396                                rates |= SNDRV_PCM_RATE_32000;
 397                                break;
 398                        case 44100:
 399                                rates |= SNDRV_PCM_RATE_44100;
 400                                break;
 401                        case 48000:
 402                                rates |= SNDRV_PCM_RATE_48000;
 403                                break;
 404                        case 64000:
 405                                rates |= SNDRV_PCM_RATE_64000;
 406                                break;
 407                        case 88200:
 408                                rates |= SNDRV_PCM_RATE_88200;
 409                                break;
 410                        case 96000:
 411                                rates |= SNDRV_PCM_RATE_96000;
 412                                break;
 413                        case 176400:
 414                                rates |= SNDRV_PCM_RATE_176400;
 415                                break;
 416                        case 192000:
 417                                rates |= SNDRV_PCM_RATE_192000;
 418                                break;
 419                        default: /* some other rate */
 420                                rates |= SNDRV_PCM_RATE_KNOT;
 421                        }
 422                }
 423        }
 424
 425        pcmhw->rates = rates;
 426        pcmhw->rate_min = rate_min;
 427        pcmhw->rate_max = rate_max;
 428}
 429
 430static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
 431                                         struct snd_pcm_hw_params *params)
 432{
 433        struct snd_pcm_runtime *runtime = substream->runtime;
 434        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 435        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 436        int err;
 437        u16 format;
 438        int width;
 439        unsigned int bytes_per_sec;
 440
 441        print_hwparams(substream, params);
 442        err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
 443        if (err)
 444                return err;
 445
 446        hpi_handle_error(hpi_format_create(&dpcm->format,
 447                        params_channels(params),
 448                        format, params_rate(params), 0, 0));
 449
 450        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 451                if (hpi_instream_reset(dpcm->h_stream) != 0)
 452                        return -EINVAL;
 453
 454                if (hpi_instream_set_format(
 455                        dpcm->h_stream, &dpcm->format) != 0)
 456                        return -EINVAL;
 457        }
 458
 459        dpcm->hpi_buffer_attached = 0;
 460        if (card->can_dma) {
 461                err = hpi_stream_host_buffer_attach(dpcm->h_stream,
 462                        params_buffer_bytes(params),  runtime->dma_addr);
 463                if (err == 0) {
 464                        snd_printdd(
 465                                "stream_host_buffer_attach success %u %lu\n",
 466                                params_buffer_bytes(params),
 467                                (unsigned long)runtime->dma_addr);
 468                } else {
 469                        snd_printd("stream_host_buffer_attach error %d\n",
 470                                        err);
 471                        return -ENOMEM;
 472                }
 473
 474                err = hpi_stream_get_info_ex(dpcm->h_stream, NULL,
 475                                &dpcm->hpi_buffer_attached, NULL, NULL, NULL);
 476        }
 477        bytes_per_sec = params_rate(params) * params_channels(params);
 478        width = snd_pcm_format_width(params_format(params));
 479        bytes_per_sec *= width;
 480        bytes_per_sec /= 8;
 481        if (width < 0 || bytes_per_sec == 0)
 482                return -EINVAL;
 483
 484        dpcm->bytes_per_sec = bytes_per_sec;
 485        dpcm->buffer_bytes = params_buffer_bytes(params);
 486        dpcm->period_bytes = params_period_bytes(params);
 487
 488        return 0;
 489}
 490
 491static int
 492snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
 493{
 494        struct snd_pcm_runtime *runtime = substream->runtime;
 495        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 496        if (dpcm->hpi_buffer_attached)
 497                hpi_stream_host_buffer_detach(dpcm->h_stream);
 498
 499        return 0;
 500}
 501
 502static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
 503{
 504        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 505        kfree(dpcm);
 506}
 507
 508static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
 509                                            substream)
 510{
 511        struct snd_pcm_runtime *runtime = substream->runtime;
 512        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 513        int expiry;
 514
 515        expiry = HZ / 200;
 516
 517        expiry = max(expiry, 1); /* don't let it be zero! */
 518        mod_timer(&dpcm->timer, jiffies + expiry);
 519        dpcm->respawn_timer = 1;
 520}
 521
 522static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
 523{
 524        struct snd_pcm_runtime *runtime = substream->runtime;
 525        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 526
 527        dpcm->respawn_timer = 0;
 528        del_timer(&dpcm->timer);
 529}
 530
 531static void snd_card_asihpi_pcm_int_start(struct snd_pcm_substream *substream)
 532{
 533        struct snd_card_asihpi_pcm *dpcm;
 534        struct snd_card_asihpi *card;
 535
 536        dpcm = (struct snd_card_asihpi_pcm *)substream->runtime->private_data;
 537        card = snd_pcm_substream_chip(substream);
 538
 539        WARN_ON(in_interrupt());
 540        card->llmode_streampriv = dpcm;
 541
 542        hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
 543                HPI_ADAPTER_PROPERTY_IRQ_RATE,
 544                card->update_interval_frames, 0));
 545}
 546
 547static void snd_card_asihpi_pcm_int_stop(struct snd_pcm_substream *substream)
 548{
 549        struct snd_card_asihpi *card;
 550
 551        card = snd_pcm_substream_chip(substream);
 552
 553        hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index,
 554                HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0));
 555
 556        card->llmode_streampriv = NULL;
 557}
 558
 559static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
 560                                           int cmd)
 561{
 562        struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
 563        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 564        struct snd_pcm_substream *s;
 565        u16 e;
 566        char name[16];
 567
 568        snd_pcm_debug_name(substream, name, sizeof(name));
 569
 570        switch (cmd) {
 571        case SNDRV_PCM_TRIGGER_START:
 572                snd_printdd("%s trigger start\n", name);
 573                snd_pcm_group_for_each_entry(s, substream) {
 574                        struct snd_pcm_runtime *runtime = s->runtime;
 575                        struct snd_card_asihpi_pcm *ds = runtime->private_data;
 576
 577                        if (snd_pcm_substream_chip(s) != card)
 578                                continue;
 579
 580                        /* don't link Cap and Play */
 581                        if (substream->stream != s->stream)
 582                                continue;
 583
 584                        ds->drained_count = 0;
 585                        if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 586                                /* How do I know how much valid data is present
 587                                * in buffer? Must be at least one period!
 588                                * Guessing 2 periods, but if
 589                                * buffer is bigger it may contain even more
 590                                * data??
 591                                */
 592                                unsigned int preload = ds->period_bytes * 1;
 593                                snd_printddd("%d preload %d\n", s->number, preload);
 594                                hpi_handle_error(hpi_outstream_write_buf(
 595                                                ds->h_stream,
 596                                                &runtime->dma_area[0],
 597                                                preload,
 598                                                &ds->format));
 599                                ds->pcm_buf_host_rw_ofs = preload;
 600                        }
 601
 602                        if (card->support_grouping) {
 603                                snd_printdd("%d group\n", s->number);
 604                                e = hpi_stream_group_add(
 605                                        dpcm->h_stream,
 606                                        ds->h_stream);
 607                                if (!e) {
 608                                        snd_pcm_trigger_done(s, substream);
 609                                } else {
 610                                        hpi_handle_error(e);
 611                                        break;
 612                                }
 613                        } else
 614                                break;
 615                }
 616                /* start the master stream */
 617                card->pcm_start(substream);
 618                if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ||
 619                        !card->can_dma)
 620                        hpi_handle_error(hpi_stream_start(dpcm->h_stream));
 621                break;
 622
 623        case SNDRV_PCM_TRIGGER_STOP:
 624                snd_printdd("%s trigger stop\n", name);
 625                card->pcm_stop(substream);
 626                snd_pcm_group_for_each_entry(s, substream) {
 627                        if (snd_pcm_substream_chip(s) != card)
 628                                continue;
 629                        /* don't link Cap and Play */
 630                        if (substream->stream != s->stream)
 631                                continue;
 632
 633                        /*? workaround linked streams don't
 634                        transition to SETUP 20070706*/
 635                        s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
 636
 637                        if (card->support_grouping) {
 638                                snd_printdd("%d group\n", s->number);
 639                                snd_pcm_trigger_done(s, substream);
 640                        } else
 641                                break;
 642                }
 643
 644                /* _prepare and _hwparams reset the stream */
 645                hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
 646                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 647                        hpi_handle_error(
 648                                hpi_outstream_reset(dpcm->h_stream));
 649
 650                if (card->support_grouping)
 651                        hpi_handle_error(hpi_stream_group_reset(dpcm->h_stream));
 652                break;
 653
 654        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 655                snd_printdd("%s trigger pause release\n", name);
 656                card->pcm_start(substream);
 657                hpi_handle_error(hpi_stream_start(dpcm->h_stream));
 658                break;
 659        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 660                snd_printdd("%s trigger pause push\n", name);
 661                card->pcm_stop(substream);
 662                hpi_handle_error(hpi_stream_stop(dpcm->h_stream));
 663                break;
 664        default:
 665                snd_printd(KERN_ERR "\tINVALID\n");
 666                return -EINVAL;
 667        }
 668
 669        return 0;
 670}
 671
 672/*algorithm outline
 673 Without linking degenerates to getting single stream pos etc
 674 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
 675*/
 676/*
 677pcm_buf_dma_ofs=get_buf_pos(s);
 678for_each_linked_stream(s) {
 679        pcm_buf_dma_ofs=get_buf_pos(s);
 680        min_buf_pos = modulo_min(min_buf_pos, pcm_buf_dma_ofs, buffer_bytes)
 681        new_data = min(new_data, calc_new_data(pcm_buf_dma_ofs,irq_pos)
 682}
 683timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
 684for_each_linked_stream(s) {
 685        s->pcm_buf_dma_ofs = min_buf_pos;
 686        if (new_data > period_bytes) {
 687                if (mmap) {
 688                        irq_pos = (irq_pos + period_bytes) % buffer_bytes;
 689                        if (playback) {
 690                                write(period_bytes);
 691                        } else {
 692                                read(period_bytes);
 693                        }
 694                }
 695                snd_pcm_period_elapsed(s);
 696        }
 697}
 698*/
 699
 700/** Minimum of 2 modulo values.  Works correctly when the difference between
 701* the values is less than half the modulus
 702*/
 703static inline unsigned int modulo_min(unsigned int a, unsigned int b,
 704                                        unsigned long int modulus)
 705{
 706        unsigned int result;
 707        if (((a-b) % modulus) < (modulus/2))
 708                result = b;
 709        else
 710                result = a;
 711
 712        return result;
 713}
 714
 715/** Timer function, equivalent to interrupt service routine for cards
 716*/
 717static void snd_card_asihpi_timer_function(struct timer_list *t)
 718{
 719        struct snd_card_asihpi_pcm *dpcm = from_timer(dpcm, t, timer);
 720        struct snd_pcm_substream *substream = dpcm->substream;
 721        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 722        struct snd_pcm_runtime *runtime;
 723        struct snd_pcm_substream *s;
 724        unsigned int newdata = 0;
 725        unsigned int pcm_buf_dma_ofs, min_buf_pos = 0;
 726        unsigned int remdata, xfercount, next_jiffies;
 727        int first = 1;
 728        int loops = 0;
 729        u16 state;
 730        u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
 731        char name[16];
 732
 733
 734        snd_pcm_debug_name(substream, name, sizeof(name));
 735
 736        /* find minimum newdata and buffer pos in group */
 737        snd_pcm_group_for_each_entry(s, substream) {
 738                struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
 739                runtime = s->runtime;
 740
 741                if (snd_pcm_substream_chip(s) != card)
 742                        continue;
 743
 744                /* don't link Cap and Play */
 745                if (substream->stream != s->stream)
 746                        continue;
 747
 748                hpi_handle_error(hpi_stream_get_info_ex(
 749                                        ds->h_stream, &state,
 750                                        &buffer_size, &bytes_avail,
 751                                        &samples_played, &on_card_bytes));
 752
 753                /* number of bytes in on-card buffer */
 754                runtime->delay = on_card_bytes;
 755
 756                if (!card->can_dma)
 757                        on_card_bytes = bytes_avail;
 758
 759                if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 760                        pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail;
 761                        if (state == HPI_STATE_STOPPED) {
 762                                if (bytes_avail == 0) {
 763                                        hpi_handle_error(hpi_stream_start(ds->h_stream));
 764                                        snd_printdd("P%d start\n", s->number);
 765                                        ds->drained_count = 0;
 766                                }
 767                        } else if (state == HPI_STATE_DRAINED) {
 768                                snd_printd(KERN_WARNING "P%d drained\n",
 769                                                s->number);
 770                                ds->drained_count++;
 771                                if (ds->drained_count > 20) {
 772                                        snd_pcm_stop_xrun(s);
 773                                        continue;
 774                                }
 775                        } else {
 776                                ds->drained_count = 0;
 777                        }
 778                } else
 779                        pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
 780
 781                if (first) {
 782                        /* can't statically init min when wrap is involved */
 783                        min_buf_pos = pcm_buf_dma_ofs;
 784                        newdata = (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes;
 785                        first = 0;
 786                } else {
 787                        min_buf_pos =
 788                                modulo_min(min_buf_pos, pcm_buf_dma_ofs, UINT_MAX+1L);
 789                        newdata = min(
 790                                (pcm_buf_dma_ofs - ds->pcm_buf_elapsed_dma_ofs) % ds->buffer_bytes,
 791                                newdata);
 792                }
 793
 794                snd_printddd(
 795                        "timer1, %s, %d, S=%d, elap=%d, rw=%d, dsp=%d, left=%d, aux=%d, space=%d, hw_ptr=%ld, appl_ptr=%ld\n",
 796                        name, s->number, state,
 797                        ds->pcm_buf_elapsed_dma_ofs,
 798                        ds->pcm_buf_host_rw_ofs,
 799                        pcm_buf_dma_ofs,
 800                        (int)bytes_avail,
 801
 802                        (int)on_card_bytes,
 803                        buffer_size-bytes_avail,
 804                        (unsigned long)frames_to_bytes(runtime,
 805                                                runtime->status->hw_ptr),
 806                        (unsigned long)frames_to_bytes(runtime,
 807                                                runtime->control->appl_ptr)
 808                );
 809                loops++;
 810        }
 811        pcm_buf_dma_ofs = min_buf_pos;
 812
 813        remdata = newdata % dpcm->period_bytes;
 814        xfercount = newdata - remdata; /* a multiple of period_bytes */
 815        /* come back when on_card_bytes has decreased enough to allow
 816           write to happen, or when data has been consumed to make another
 817           period
 818        */
 819        if (xfercount && (on_card_bytes  > dpcm->period_bytes))
 820                next_jiffies = ((on_card_bytes - dpcm->period_bytes) * HZ / dpcm->bytes_per_sec);
 821        else
 822                next_jiffies = ((dpcm->period_bytes - remdata) * HZ / dpcm->bytes_per_sec);
 823
 824        next_jiffies = max(next_jiffies, 1U);
 825        dpcm->timer.expires = jiffies + next_jiffies;
 826        snd_printddd("timer2, jif=%d, buf_pos=%d, newdata=%d, xfer=%d\n",
 827                        next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
 828
 829        snd_pcm_group_for_each_entry(s, substream) {
 830                struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
 831
 832                /* don't link Cap and Play */
 833                if (substream->stream != s->stream)
 834                        continue;
 835
 836                /* Store dma offset for use by pointer callback */
 837                ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
 838
 839                if (xfercount &&
 840                        /* Limit use of on card fifo for playback */
 841                        ((on_card_bytes <= ds->period_bytes) ||
 842                        (s->stream == SNDRV_PCM_STREAM_CAPTURE)))
 843
 844                {
 845
 846                        unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes;
 847                        unsigned int xfer1, xfer2;
 848                        char *pd = &s->runtime->dma_area[buf_ofs];
 849
 850                        if (card->can_dma) { /* buffer wrap is handled at lower level */
 851                                xfer1 = xfercount;
 852                                xfer2 = 0;
 853                        } else {
 854                                xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs);
 855                                xfer2 = xfercount - xfer1;
 856                        }
 857
 858                        if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 859                                snd_printddd("write1, P=%d, xfer=%d, buf_ofs=%d\n",
 860                                        s->number, xfer1, buf_ofs);
 861                                hpi_handle_error(
 862                                        hpi_outstream_write_buf(
 863                                                ds->h_stream, pd, xfer1,
 864                                                &ds->format));
 865
 866                                if (xfer2) {
 867                                        pd = s->runtime->dma_area;
 868
 869                                        snd_printddd("write2, P=%d, xfer=%d, buf_ofs=%d\n",
 870                                                        s->number,
 871                                                        xfercount - xfer1, buf_ofs);
 872                                        hpi_handle_error(
 873                                                hpi_outstream_write_buf(
 874                                                        ds->h_stream, pd,
 875                                                        xfercount - xfer1,
 876                                                        &ds->format));
 877                                }
 878                        } else {
 879                                snd_printddd("read1, C=%d, xfer=%d\n",
 880                                        s->number, xfer1);
 881                                hpi_handle_error(
 882                                        hpi_instream_read_buf(
 883                                                ds->h_stream,
 884                                                pd, xfer1));
 885                                if (xfer2) {
 886                                        pd = s->runtime->dma_area;
 887                                        snd_printddd("read2, C=%d, xfer=%d\n",
 888                                                s->number, xfer2);
 889                                        hpi_handle_error(
 890                                                hpi_instream_read_buf(
 891                                                        ds->h_stream,
 892                                                        pd, xfer2));
 893                                }
 894                        }
 895                        /* ? host_rw_ofs always ahead of elapsed_dma_ofs by preload size? */
 896                        ds->pcm_buf_host_rw_ofs += xfercount;
 897                        ds->pcm_buf_elapsed_dma_ofs += xfercount;
 898                        snd_pcm_period_elapsed(s);
 899                }
 900        }
 901
 902        if (!card->hpi->interrupt_mode && dpcm->respawn_timer)
 903                add_timer(&dpcm->timer);
 904}
 905
 906static void snd_card_asihpi_isr(struct hpi_adapter *a)
 907{
 908        struct snd_card_asihpi *asihpi;
 909
 910        WARN_ON(!a || !a->snd_card || !a->snd_card->private_data);
 911        asihpi = (struct snd_card_asihpi *)a->snd_card->private_data;
 912        if (asihpi->llmode_streampriv)
 913                snd_card_asihpi_timer_function(
 914                        &asihpi->llmode_streampriv->timer);
 915}
 916
 917/***************************** PLAYBACK OPS ****************/
 918static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
 919                                            substream)
 920{
 921        struct snd_pcm_runtime *runtime = substream->runtime;
 922        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 923
 924        snd_printdd("P%d prepare\n", substream->number);
 925
 926        hpi_handle_error(hpi_outstream_reset(dpcm->h_stream));
 927        dpcm->pcm_buf_host_rw_ofs = 0;
 928        dpcm->pcm_buf_dma_ofs = 0;
 929        dpcm->pcm_buf_elapsed_dma_ofs = 0;
 930        return 0;
 931}
 932
 933static snd_pcm_uframes_t
 934snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
 935{
 936        struct snd_pcm_runtime *runtime = substream->runtime;
 937        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 938        snd_pcm_uframes_t ptr;
 939        char name[16];
 940        snd_pcm_debug_name(substream, name, sizeof(name));
 941
 942        ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs  % dpcm->buffer_bytes);
 943        snd_printddd("%s, pointer=%ld\n", name, (unsigned long)ptr);
 944        return ptr;
 945}
 946
 947static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
 948                                                u32 h_stream)
 949{
 950        struct hpi_format hpi_format;
 951        u16 format;
 952        u16 err;
 953        u32 h_control;
 954        u32 sample_rate = 48000;
 955        u64 formats = 0;
 956
 957        /* on cards without SRC, must query at valid rate,
 958        * maybe set by external sync
 959        */
 960        err = hpi_mixer_get_control(asihpi->h_mixer,
 961                                  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
 962                                  HPI_CONTROL_SAMPLECLOCK, &h_control);
 963
 964        if (!err)
 965                err = hpi_sample_clock_get_sample_rate(h_control,
 966                                &sample_rate);
 967
 968        for (format = HPI_FORMAT_PCM8_UNSIGNED;
 969             format <= HPI_FORMAT_PCM24_SIGNED; format++) {
 970                err = hpi_format_create(&hpi_format, asihpi->out_max_chans,
 971                                        format, sample_rate, 128000, 0);
 972                if (!err)
 973                        err = hpi_outstream_query_format(h_stream, &hpi_format);
 974                if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
 975                        formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
 976        }
 977        return formats;
 978}
 979
 980static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
 981{
 982        struct snd_pcm_runtime *runtime = substream->runtime;
 983        struct snd_card_asihpi_pcm *dpcm;
 984        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 985        struct snd_pcm_hardware snd_card_asihpi_playback;
 986        int err;
 987
 988        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
 989        if (dpcm == NULL)
 990                return -ENOMEM;
 991
 992        err = hpi_outstream_open(card->hpi->adapter->index,
 993                              substream->number, &dpcm->h_stream);
 994        hpi_handle_error(err);
 995        if (err)
 996                kfree(dpcm);
 997        if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
 998                return -EBUSY;
 999        if (err)
1000                return -EIO;
1001
1002        /*? also check ASI5000 samplerate source
1003            If external, only support external rate.
1004            If internal and other stream playing, can't switch
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        /* snd_card_asihpi_playback.fifo_size = 0; */
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        /* struct is copied, so can create initializer dynamically */
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
1070static 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
1081static 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/***************************** CAPTURE OPS ****************/
1092static snd_pcm_uframes_t
1093snd_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        /* NOTE Unlike playback can't use actual samples_played
1102                for the capture position, because those samples aren't yet in
1103                the local buffer available for reading.
1104        */
1105        return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes);
1106}
1107
1108static 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
1122static 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        /* on cards without SRC, must query at valid rate,
1133                maybe set by external sync */
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
1155static 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        /* snd_card_asihpi_capture.fifo_size = 0; */
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
1232static 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
1240static 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
1250static 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        /* pointer to ops struct is stored, dont change ops afterwards! */
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        /*? do we want to emulate MMAP for non-BBM cards?
1277        Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
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/***************************** MIXER CONTROLS ****************/
1286struct 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]; /* copied to snd_ctl_elem_id.name[44]; */
1295};
1296
1297static 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/* Number of strings must match the enumerations for HPI_TUNER_BAND in hpi.h */
1311compile_time_assert(
1312        (ARRAY_SIZE(asihpi_tuner_band_names) ==
1313                (HPI_TUNER_BAND_LAST+1)),
1314        assert_tuner_band_names_size);
1315
1316static 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/* Number of strings must match the enumerations for HPI_SOURCENODES in hpi.h */
1335compile_time_assert(
1336        (ARRAY_SIZE(asihpi_src_names) ==
1337                (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1338        assert_src_names_size);
1339
1340static 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/* Number of strings must match the enumerations for HPI_DESTNODES in hpi.h */
1355compile_time_assert(
1356        (ARRAY_SIZE(asihpi_dst_names) ==
1357                (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1358        assert_dst_names_size);
1359
1360static 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/* Convert HPI control name and location into ALSA control name */
1375static 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 = ""; /* clock is neither capture nor playback */
1388        else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
1389                dir = "Capture ";  /* On or towards a PCM capture destination*/
1390        else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) &&
1391                (!hpi_ctl->dst_node_type))
1392                dir = "Capture "; /* On a source node that is not PCM playback */
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 "; /* Between an input and an output */
1397        else
1398                dir = "Playback "; /* PCM Playback source, or  output node */
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        /* printk(KERN_INFO "Adding %s %d to %d ",  hpi_ctl->name,
1419                hpi_ctl->wSrcNodeType, hpi_ctl->wDstNodeType); */
1420}
1421
1422/*------------------------------------------------------------
1423   Volume controls
1424 ------------------------------------------------------------*/
1425#define VOL_STEP_mB 1
1426static 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        /* native gains are in millibels */
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
1457static 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
1470static 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        /*  change = asihpi->mixer_volume[addr][0] != left ||
1481           asihpi->mixer_volume[addr][1] != right;
1482         */
1483        hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB));
1484        return 1;
1485}
1486
1487static 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
1491static 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
1503static 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        /* HPI currently only supports all or none muting of multichannel volume
1508        ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
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
1515static 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   Level controls
1548 ------------------------------------------------------------*/
1549static 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
1575static 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
1590static 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        /*  change = asihpi->mixer_level[addr][0] != left ||
1602           asihpi->mixer_level[addr][1] != right;
1603         */
1604        change = 1;
1605        hpi_handle_error(hpi_level_set_gain(h_control, an_gain_mB));
1606        return change;
1607}
1608
1609static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1610
1611static 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        /* can't use 'volume' cos some nodes have volume as well */
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   AESEBU controls
1631 ------------------------------------------------------------*/
1632
1633/* AESEBU format */
1634static const char * const asihpi_aesebu_format_names[] = {
1635        "N/A", "S/PDIF", "AES/EBU" };
1636
1637static 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
1643static 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        /* default to N/A */
1653        ucontrol->value.enumerated.item[0] = 0;
1654        /* return success but set the control to N/A */
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
1665static 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        /* default to S/PDIF */
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
1685static 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
1691static 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
1697static 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
1710static 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
1722static 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
1747static 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
1753static 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
1760static 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   Tuner controls
1777 ------------------------------------------------------------*/
1778
1779/* Gain */
1780
1781static 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
1804static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1805                                 struct snd_ctl_elem_value *ucontrol)
1806{
1807        /*
1808        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
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
1819static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1820                                 struct snd_ctl_elem_value *ucontrol)
1821{
1822        /*
1823        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
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/* Band  */
1835
1836static 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
1855static 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
1870static 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        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
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
1896static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1897                                 struct snd_ctl_elem_value *ucontrol)
1898{
1899        /*
1900        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
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/* Freq */
1921
1922static 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                /* skip band with bogus stepping */
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
1967static 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
1979static 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/* Tuner control group initializer  */
1992static 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   Meter controls
2029 ------------------------------------------------------------*/
2030static 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/* linear values for 10dB steps */
2048static const int log2lin[] = {
2049        0x7FFFFFFF, /* 0dB */
2050        679093956,
2051        214748365,
2052         67909396,
2053         21474837,
2054          6790940,
2055          2147484, /* -60dB */
2056           679094,
2057           214748, /* -80 */
2058            67909,
2059            21475, /* -100 */
2060             6791,
2061             2147,
2062              679,
2063              214,
2064               68,
2065               21,
2066                7,
2067                2
2068};
2069
2070static 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                        /* -ve is log value in millibels < -60dB,
2087                        * convert to (roughly!) linear,
2088                        */
2089                        ucontrol->value.integer.value[i] =
2090                                        log2lin[an_gain_mB[i] / -1000];
2091                }
2092        }
2093        return 0;
2094}
2095
2096static 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   Multiplexer controls
2115 ------------------------------------------------------------*/
2116static 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
2133static 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
2158static 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        /* Should cache this search result! */
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
2187static 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
2208static 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   Channel mode controls
2226 ------------------------------------------------------------*/
2227static 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        /* HPI channel mode values can be from 1 to 6
2244        Some adapters only support a contiguous subset
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
2259static 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
2273static 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
2287static 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   Sampleclock source  controls
2304 ------------------------------------------------------------*/
2305static 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        /* Number of strings must match expected enumerated values */
2313        compile_time_assert(
2314                (ARRAY_SIZE(sampleclock_sources) == MAX_CLOCKSOURCES),
2315                assert_sampleclock_sources_size);
2316
2317static 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
2336static 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
2364static 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   Clkrate controls
2390 ------------------------------------------------------------*/
2391/* Need to change this to enumerated control with list of rates */
2392static 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
2404static 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
2419static 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        /*  change = asihpi->mixer_clkrate[addr][0] != left ||
2426           asihpi->mixer_clkrate[addr][1] != right;
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
2434static 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
2446static 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
2461static 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                /* already will have picked up index 0 above */
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   Mixer
2540 ------------------------------------------------------------*/
2541
2542static 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                /* ASI50xx in SSX mode has multiple meters on the same node.
2591                   Use subindex to create distinct ALSA controls
2592                   for any duplicated controls.
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:    /* ignore these */
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   /proc interface
2666 ------------------------------------------------------------*/
2667
2668static void
2669snd_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
2716static 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   HWDEP
2724 ------------------------------------------------------------*/
2725
2726static 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
2735static 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
2743static 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/* results in /dev/snd/hwC#D0 file for each card with index #
2754   also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2755*/
2756static 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   CARD
2775 ------------------------------------------------------------*/
2776static 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        /* Should this be enable[hpi->index] ? */
2793        if (!enable[dev]) {
2794                dev++;
2795                return -ENOENT;
2796        }
2797
2798        /* Initialise low-level HPI driver */
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        /* first try to give the card the same index as its hardware index */
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                /* if that fails, try the default index==next available */
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) { /* assume LL mode */
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        /* always create, can be enabled or disabled dynamically
2909            by enable_hwdep  module param*/
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
2931static void snd_asihpi_remove(struct pci_dev *pci_dev)
2932{
2933        struct hpi_adapter *hpi = pci_get_drvdata(pci_dev);
2934
2935        /* Stop interrupts */
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
2947static 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};
2956MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2957
2958static 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
2965static int __init snd_asihpi_init(void)
2966{
2967        asihpi_init();
2968        return pci_register_driver(&driver);
2969}
2970
2971static void __exit snd_asihpi_exit(void)
2972{
2973
2974        pci_unregister_driver(&driver);
2975        asihpi_exit();
2976}
2977
2978module_init(snd_asihpi_init)
2979module_exit(snd_asihpi_exit)
2980
2981