linux/sound/pci/asihpi/asihpi.c
<<
>>
Prefs
   1/*
   2 *  Asihpi soundcard
   3 *  Copyright (c) by AudioScience Inc <alsa@audioscience.com>
   4 *
   5 *   This program is free software; you can redistribute it and/or modify
   6 *   it under the terms of version 2 of the GNU General Public License as
   7 *   published by the Free Software Foundation;
   8 *
   9 *   This program is distributed in the hope that it will be useful,
  10 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 *   GNU General Public License for more details.
  13 *
  14 *   You should have received a copy of the GNU General Public License
  15 *   along with this program; if not, write to the Free Software
  16 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  17 *
  18 *
  19 *  The following is not a condition of use, merely a request:
  20 *  If you modify this program, particularly if you fix errors, AudioScience Inc
  21 *  would appreciate it if you grant us the right to use those modifications
  22 *  for any purpose including commercial applications.
  23 */
  24/* >0: print Hw params, timer vars. >1: print stream write/copy sizes  */
  25#define REALLY_VERBOSE_LOGGING 0
  26
  27#if REALLY_VERBOSE_LOGGING
  28#define VPRINTK1 snd_printd
  29#else
  30#define VPRINTK1(...)
  31#endif
  32
  33#if REALLY_VERBOSE_LOGGING > 1
  34#define VPRINTK2 snd_printd
  35#else
  36#define VPRINTK2(...)
  37#endif
  38
  39#ifndef ASI_STYLE_NAMES
  40/* not sure how ALSA style name should look */
  41#define ASI_STYLE_NAMES 1
  42#endif
  43
  44#include "hpi_internal.h"
  45#include "hpimsginit.h"
  46#include "hpioctl.h"
  47
  48#include <linux/pci.h>
  49#include <linux/init.h>
  50#include <linux/jiffies.h>
  51#include <linux/slab.h>
  52#include <linux/time.h>
  53#include <linux/wait.h>
  54#include <sound/core.h>
  55#include <sound/control.h>
  56#include <sound/pcm.h>
  57#include <sound/pcm_params.h>
  58#include <sound/info.h>
  59#include <sound/initval.h>
  60#include <sound/tlv.h>
  61#include <sound/hwdep.h>
  62
  63
  64MODULE_LICENSE("GPL");
  65MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>");
  66MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
  67
  68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;      /* index 0-MAX */
  69static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;       /* ID for this card */
  70static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
  71static int enable_hpi_hwdep = 1;
  72
  73module_param_array(index, int, NULL, S_IRUGO);
  74MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard.");
  75
  76module_param_array(id, charp, NULL, S_IRUGO);
  77MODULE_PARM_DESC(id, "ALSA ID string for AudioScience soundcard.");
  78
  79module_param_array(enable, bool, NULL, S_IRUGO);
  80MODULE_PARM_DESC(enable, "ALSA enable AudioScience soundcard.");
  81
  82module_param(enable_hpi_hwdep, bool, S_IRUGO|S_IWUSR);
  83MODULE_PARM_DESC(enable_hpi_hwdep,
  84                "ALSA enable HPI hwdep for AudioScience soundcard ");
  85
  86/* identify driver */
  87#ifdef KERNEL_ALSA_BUILD
  88static char *build_info = "built using headers from kernel source";
  89module_param(build_info, charp, S_IRUGO);
  90MODULE_PARM_DESC(build_info, "built using headers from kernel source");
  91#else
  92static char *build_info = "built within ALSA source";
  93module_param(build_info, charp, S_IRUGO);
  94MODULE_PARM_DESC(build_info, "built within ALSA source");
  95#endif
  96
  97/* set to 1 to dump every control from adapter to log */
  98static const int mixer_dump;
  99
 100#define DEFAULT_SAMPLERATE 44100
 101static int adapter_fs = DEFAULT_SAMPLERATE;
 102
 103static struct hpi_hsubsys *ss;  /* handle to HPI audio subsystem */
 104
 105/* defaults */
 106#define PERIODS_MIN 2
 107#define PERIOD_BYTES_MIN  2304
 108#define BUFFER_BYTES_MAX (512 * 1024)
 109
 110/*#define TIMER_MILLISECONDS 20
 111#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000)
 112*/
 113
 114#define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
 115
 116struct clk_source {
 117        int source;
 118        int index;
 119        char *name;
 120};
 121
 122struct clk_cache {
 123        int count;
 124        int has_local;
 125        struct clk_source s[MAX_CLOCKSOURCES];
 126};
 127
 128/* Per card data */
 129struct snd_card_asihpi {
 130        struct snd_card *card;
 131        struct pci_dev *pci;
 132        u16 adapter_index;
 133        u32 serial_number;
 134        u16 type;
 135        u16 version;
 136        u16 num_outstreams;
 137        u16 num_instreams;
 138
 139        u32 h_mixer;
 140        struct clk_cache cc;
 141
 142        u16 support_mmap;
 143        u16 support_grouping;
 144        u16 support_mrx;
 145        u16 update_interval_frames;
 146        u16 in_max_chans;
 147        u16 out_max_chans;
 148};
 149
 150/* Per stream data */
 151struct snd_card_asihpi_pcm {
 152        struct timer_list timer;
 153        unsigned int respawn_timer;
 154        unsigned int hpi_buffer_attached;
 155        unsigned int pcm_size;
 156        unsigned int pcm_count;
 157        unsigned int bytes_per_sec;
 158        unsigned int pcm_irq_pos;       /* IRQ position */
 159        unsigned int pcm_buf_pos;       /* position in buffer */
 160        struct snd_pcm_substream *substream;
 161        u32 h_stream;
 162        struct hpi_format format;
 163};
 164
 165/* universal stream verbs work with out or in stream handles */
 166
 167/* Functions to allow driver to give a buffer to HPI for busmastering */
 168
 169static u16 hpi_stream_host_buffer_attach(
 170        struct hpi_hsubsys *hS,
 171        u32 h_stream,   /* handle to outstream. */
 172        u32 size_in_bytes, /* size in bytes of bus mastering buffer */
 173        u32 pci_address
 174)
 175{
 176        struct hpi_message hm;
 177        struct hpi_response hr;
 178        unsigned int obj = hpi_handle_object(h_stream);
 179
 180        if (!h_stream)
 181                return HPI_ERROR_INVALID_OBJ;
 182        hpi_init_message_response(&hm, &hr, obj,
 183                        obj == HPI_OBJ_OSTREAM ?
 184                                HPI_OSTREAM_HOSTBUFFER_ALLOC :
 185                                HPI_ISTREAM_HOSTBUFFER_ALLOC);
 186
 187        hpi_handle_to_indexes(h_stream, &hm.adapter_index,
 188                                &hm.obj_index);
 189
 190        hm.u.d.u.buffer.buffer_size = size_in_bytes;
 191        hm.u.d.u.buffer.pci_address = pci_address;
 192        hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_GRANTADAPTER;
 193        hpi_send_recv(&hm, &hr);
 194        return hr.error;
 195}
 196
 197static u16 hpi_stream_host_buffer_detach(
 198        struct hpi_hsubsys *hS,
 199        u32  h_stream
 200)
 201{
 202        struct hpi_message hm;
 203        struct hpi_response hr;
 204        unsigned int obj = hpi_handle_object(h_stream);
 205
 206        if (!h_stream)
 207                return HPI_ERROR_INVALID_OBJ;
 208
 209        hpi_init_message_response(&hm, &hr,  obj,
 210                        obj == HPI_OBJ_OSTREAM ?
 211                                HPI_OSTREAM_HOSTBUFFER_FREE :
 212                                HPI_ISTREAM_HOSTBUFFER_FREE);
 213
 214        hpi_handle_to_indexes(h_stream, &hm.adapter_index,
 215                                &hm.obj_index);
 216        hm.u.d.u.buffer.command = HPI_BUFFER_CMD_INTERNAL_REVOKEADAPTER;
 217        hpi_send_recv(&hm, &hr);
 218        return hr.error;
 219}
 220
 221static inline u16 hpi_stream_start(struct hpi_hsubsys *hS, u32 h_stream)
 222{
 223        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 224                return hpi_outstream_start(hS, h_stream);
 225        else
 226                return hpi_instream_start(hS, h_stream);
 227}
 228
 229static inline u16 hpi_stream_stop(struct hpi_hsubsys *hS, u32 h_stream)
 230{
 231        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 232                return hpi_outstream_stop(hS, h_stream);
 233        else
 234                return hpi_instream_stop(hS, h_stream);
 235}
 236
 237static inline u16 hpi_stream_get_info_ex(
 238    struct hpi_hsubsys *hS,
 239    u32 h_stream,
 240    u16        *pw_state,
 241    u32        *pbuffer_size,
 242    u32        *pdata_in_buffer,
 243    u32        *psample_count,
 244    u32        *pauxiliary_data
 245)
 246{
 247        if (hpi_handle_object(h_stream)  ==  HPI_OBJ_OSTREAM)
 248                return hpi_outstream_get_info_ex(hS, h_stream, pw_state,
 249                                        pbuffer_size, pdata_in_buffer,
 250                                        psample_count, pauxiliary_data);
 251        else
 252                return hpi_instream_get_info_ex(hS, h_stream, pw_state,
 253                                        pbuffer_size, pdata_in_buffer,
 254                                        psample_count, pauxiliary_data);
 255}
 256
 257static inline u16 hpi_stream_group_add(struct hpi_hsubsys *hS,
 258                                        u32 h_master,
 259                                        u32 h_stream)
 260{
 261        if (hpi_handle_object(h_master) ==  HPI_OBJ_OSTREAM)
 262                return hpi_outstream_group_add(hS, h_master, h_stream);
 263        else
 264                return hpi_instream_group_add(hS, h_master, h_stream);
 265}
 266
 267static inline u16 hpi_stream_group_reset(struct hpi_hsubsys *hS,
 268                                                u32 h_stream)
 269{
 270        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 271                return hpi_outstream_group_reset(hS, h_stream);
 272        else
 273                return hpi_instream_group_reset(hS, h_stream);
 274}
 275
 276static inline u16 hpi_stream_group_get_map(struct hpi_hsubsys *hS,
 277                                u32 h_stream, u32 *mo, u32 *mi)
 278{
 279        if (hpi_handle_object(h_stream) ==  HPI_OBJ_OSTREAM)
 280                return hpi_outstream_group_get_map(hS, h_stream, mo, mi);
 281        else
 282                return hpi_instream_group_get_map(hS, h_stream, mo, mi);
 283}
 284
 285static u16 handle_error(u16 err, int line, char *filename)
 286{
 287        if (err)
 288                printk(KERN_WARNING
 289                        "in file %s, line %d: HPI error %d\n",
 290                        filename, line, err);
 291        return err;
 292}
 293
 294#define hpi_handle_error(x)  handle_error(x, __LINE__, __FILE__)
 295
 296/***************************** GENERAL PCM ****************/
 297#if REALLY_VERBOSE_LOGGING
 298static void print_hwparams(struct snd_pcm_hw_params *p)
 299{
 300        snd_printd("HWPARAMS \n");
 301        snd_printd("samplerate %d \n", params_rate(p));
 302        snd_printd("channels %d \n", params_channels(p));
 303        snd_printd("format %d \n", params_format(p));
 304        snd_printd("subformat %d \n", params_subformat(p));
 305        snd_printd("buffer bytes %d \n", params_buffer_bytes(p));
 306        snd_printd("period bytes %d \n", params_period_bytes(p));
 307        snd_printd("access %d \n", params_access(p));
 308        snd_printd("period_size %d \n", params_period_size(p));
 309        snd_printd("periods %d \n", params_periods(p));
 310        snd_printd("buffer_size %d \n", params_buffer_size(p));
 311}
 312#else
 313#define print_hwparams(x)
 314#endif
 315
 316static snd_pcm_format_t hpi_to_alsa_formats[] = {
 317        -1,                     /* INVALID */
 318        SNDRV_PCM_FORMAT_U8,    /* HPI_FORMAT_PCM8_UNSIGNED        1 */
 319        SNDRV_PCM_FORMAT_S16,   /* HPI_FORMAT_PCM16_SIGNED         2 */
 320        -1,                     /* HPI_FORMAT_MPEG_L1              3 */
 321        SNDRV_PCM_FORMAT_MPEG,  /* HPI_FORMAT_MPEG_L2              4 */
 322        SNDRV_PCM_FORMAT_MPEG,  /* HPI_FORMAT_MPEG_L3              5 */
 323        -1,                     /* HPI_FORMAT_DOLBY_AC2            6 */
 324        -1,                     /* HPI_FORMAT_DOLBY_AC3            7 */
 325        SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN      8 */
 326        -1,                     /* HPI_FORMAT_AA_TAGIT1_HITS       9 */
 327        -1,                     /* HPI_FORMAT_AA_TAGIT1_INSERTS   10 */
 328        SNDRV_PCM_FORMAT_S32,   /* HPI_FORMAT_PCM32_SIGNED        11 */
 329        -1,                     /* HPI_FORMAT_RAW_BITSTREAM       12 */
 330        -1,                     /* HPI_FORMAT_AA_TAGIT1_HITS_EX1  13 */
 331        SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT         14 */
 332#if 1
 333        /* ALSA can't handle 3 byte sample size together with power-of-2
 334         *  constraint on buffer_bytes, so disable this format
 335         */
 336        -1
 337#else
 338        /* SNDRV_PCM_FORMAT_S24_3LE */  /* { HPI_FORMAT_PCM24_SIGNED        15 */
 339#endif
 340};
 341
 342
 343static int snd_card_asihpi_format_alsa2hpi(snd_pcm_format_t alsa_format,
 344                                           u16 *hpi_format)
 345{
 346        u16 format;
 347
 348        for (format = HPI_FORMAT_PCM8_UNSIGNED;
 349             format <= HPI_FORMAT_PCM24_SIGNED; format++) {
 350                if (hpi_to_alsa_formats[format] == alsa_format) {
 351                        *hpi_format = format;
 352                        return 0;
 353                }
 354        }
 355
 356        snd_printd(KERN_WARNING "failed match for alsa format %d\n",
 357                   alsa_format);
 358        *hpi_format = 0;
 359        return -EINVAL;
 360}
 361
 362static void snd_card_asihpi_pcm_samplerates(struct snd_card_asihpi *asihpi,
 363                                         struct snd_pcm_hardware *pcmhw)
 364{
 365        u16 err;
 366        u32 h_control;
 367        u32 sample_rate;
 368        int idx;
 369        unsigned int rate_min = 200000;
 370        unsigned int rate_max = 0;
 371        unsigned int rates = 0;
 372
 373        if (asihpi->support_mrx) {
 374                rates |= SNDRV_PCM_RATE_CONTINUOUS;
 375                rates |= SNDRV_PCM_RATE_8000_96000;
 376                rate_min = 8000;
 377                rate_max = 100000;
 378        } else {
 379                /* on cards without SRC,
 380                   valid rates are determined by sampleclock */
 381                err = hpi_mixer_get_control(ss, asihpi->h_mixer,
 382                                          HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
 383                                          HPI_CONTROL_SAMPLECLOCK, &h_control);
 384                if (err) {
 385                        snd_printk(KERN_ERR
 386                                "no local sampleclock, err %d\n", err);
 387                }
 388
 389                for (idx = 0; idx < 100; idx++) {
 390                        if (hpi_sample_clock_query_local_rate(ss,
 391                                h_control, idx, &sample_rate)) {
 392                                if (!idx)
 393                                        snd_printk(KERN_ERR
 394                                                "local rate query failed\n");
 395
 396                                break;
 397                        }
 398
 399                        rate_min = min(rate_min, sample_rate);
 400                        rate_max = max(rate_max, sample_rate);
 401
 402                        switch (sample_rate) {
 403                        case 5512:
 404                                rates |= SNDRV_PCM_RATE_5512;
 405                                break;
 406                        case 8000:
 407                                rates |= SNDRV_PCM_RATE_8000;
 408                                break;
 409                        case 11025:
 410                                rates |= SNDRV_PCM_RATE_11025;
 411                                break;
 412                        case 16000:
 413                                rates |= SNDRV_PCM_RATE_16000;
 414                                break;
 415                        case 22050:
 416                                rates |= SNDRV_PCM_RATE_22050;
 417                                break;
 418                        case 32000:
 419                                rates |= SNDRV_PCM_RATE_32000;
 420                                break;
 421                        case 44100:
 422                                rates |= SNDRV_PCM_RATE_44100;
 423                                break;
 424                        case 48000:
 425                                rates |= SNDRV_PCM_RATE_48000;
 426                                break;
 427                        case 64000:
 428                                rates |= SNDRV_PCM_RATE_64000;
 429                                break;
 430                        case 88200:
 431                                rates |= SNDRV_PCM_RATE_88200;
 432                                break;
 433                        case 96000:
 434                                rates |= SNDRV_PCM_RATE_96000;
 435                                break;
 436                        case 176400:
 437                                rates |= SNDRV_PCM_RATE_176400;
 438                                break;
 439                        case 192000:
 440                                rates |= SNDRV_PCM_RATE_192000;
 441                                break;
 442                        default: /* some other rate */
 443                                rates |= SNDRV_PCM_RATE_KNOT;
 444                        }
 445                }
 446        }
 447
 448        /* printk(KERN_INFO "Supported rates %X %d %d\n",
 449           rates, rate_min, rate_max); */
 450        pcmhw->rates = rates;
 451        pcmhw->rate_min = rate_min;
 452        pcmhw->rate_max = rate_max;
 453}
 454
 455static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream,
 456                                         struct snd_pcm_hw_params *params)
 457{
 458        struct snd_pcm_runtime *runtime = substream->runtime;
 459        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 460        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 461        int err;
 462        u16 format;
 463        int width;
 464        unsigned int bytes_per_sec;
 465
 466        print_hwparams(params);
 467        err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
 468        if (err < 0)
 469                return err;
 470        err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format);
 471        if (err)
 472                return err;
 473
 474        VPRINTK1(KERN_INFO "format %d, %d chans, %d_hz\n",
 475                                format, params_channels(params),
 476                                params_rate(params));
 477
 478        hpi_handle_error(hpi_format_create(&dpcm->format,
 479                        params_channels(params),
 480                        format, params_rate(params), 0, 0));
 481
 482        if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 483                if (hpi_instream_reset(ss, dpcm->h_stream) != 0)
 484                        return -EINVAL;
 485
 486                if (hpi_instream_set_format(ss,
 487                        dpcm->h_stream, &dpcm->format) != 0)
 488                        return -EINVAL;
 489        }
 490
 491        dpcm->hpi_buffer_attached = 0;
 492        if (card->support_mmap) {
 493
 494                err = hpi_stream_host_buffer_attach(ss, dpcm->h_stream,
 495                        params_buffer_bytes(params),  runtime->dma_addr);
 496                if (err == 0) {
 497                        snd_printd(KERN_INFO
 498                                "stream_host_buffer_attach succeeded %u %lu\n",
 499                                params_buffer_bytes(params),
 500                                (unsigned long)runtime->dma_addr);
 501                } else {
 502                        snd_printd(KERN_INFO
 503                                        "stream_host_buffer_attach error %d\n",
 504                                        err);
 505                        return -ENOMEM;
 506                }
 507
 508                err = hpi_stream_get_info_ex(ss, dpcm->h_stream, NULL,
 509                                                &dpcm->hpi_buffer_attached,
 510                                                NULL, NULL, NULL);
 511
 512                snd_printd(KERN_INFO "stream_host_buffer_attach status 0x%x\n",
 513                                dpcm->hpi_buffer_attached);
 514        }
 515        bytes_per_sec = params_rate(params) * params_channels(params);
 516        width = snd_pcm_format_width(params_format(params));
 517        bytes_per_sec *= width;
 518        bytes_per_sec /= 8;
 519        if (width < 0 || bytes_per_sec == 0)
 520                return -EINVAL;
 521
 522        dpcm->bytes_per_sec = bytes_per_sec;
 523        dpcm->pcm_size = params_buffer_bytes(params);
 524        dpcm->pcm_count = params_period_bytes(params);
 525        snd_printd(KERN_INFO "pcm_size=%d, pcm_count=%d, bps=%d\n",
 526                        dpcm->pcm_size, dpcm->pcm_count, bytes_per_sec);
 527
 528        dpcm->pcm_irq_pos = 0;
 529        dpcm->pcm_buf_pos = 0;
 530        return 0;
 531}
 532
 533static void snd_card_asihpi_pcm_timer_start(struct snd_pcm_substream *
 534                                            substream)
 535{
 536        struct snd_pcm_runtime *runtime = substream->runtime;
 537        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 538        int expiry;
 539
 540        expiry = (dpcm->pcm_count * HZ / dpcm->bytes_per_sec);
 541        /* wait longer the first time, for samples to propagate */
 542        expiry = max(expiry, 20);
 543        dpcm->timer.expires = jiffies + expiry;
 544        dpcm->respawn_timer = 1;
 545        add_timer(&dpcm->timer);
 546}
 547
 548static void snd_card_asihpi_pcm_timer_stop(struct snd_pcm_substream *substream)
 549{
 550        struct snd_pcm_runtime *runtime = substream->runtime;
 551        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 552
 553        dpcm->respawn_timer = 0;
 554        del_timer(&dpcm->timer);
 555}
 556
 557static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
 558                                           int cmd)
 559{
 560        struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
 561        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 562        struct snd_pcm_substream *s;
 563        u16 e;
 564
 565        snd_printd("trigger %dstream %d\n",
 566                        substream->stream, substream->number);
 567        switch (cmd) {
 568        case SNDRV_PCM_TRIGGER_START:
 569                snd_pcm_group_for_each_entry(s, substream) {
 570                        struct snd_card_asihpi_pcm *ds;
 571                        ds = s->runtime->private_data;
 572
 573                        if (snd_pcm_substream_chip(s) != card)
 574                                continue;
 575
 576                        if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) &&
 577                                (card->support_mmap)) {
 578                                /* How do I know how much valid data is present
 579                                * in buffer? Just guessing 2 periods, but if
 580                                * buffer is bigger it may contain even more
 581                                * data??
 582                                */
 583                                unsigned int preload = ds->pcm_count * 2;
 584                                VPRINTK2("preload %d\n", preload);
 585                                hpi_handle_error(hpi_outstream_write_buf(
 586                                                ss, ds->h_stream,
 587                                                &s->runtime->dma_area[0],
 588                                                preload,
 589                                                &ds->format));
 590                        }
 591
 592                        if (card->support_grouping) {
 593                                VPRINTK1("\t_group %dstream %d\n", s->stream,
 594                                                s->number);
 595                                e = hpi_stream_group_add(ss,
 596                                        dpcm->h_stream,
 597                                        ds->h_stream);
 598                                if (!e) {
 599                                        snd_pcm_trigger_done(s, substream);
 600                                } else {
 601                                        hpi_handle_error(e);
 602                                        break;
 603                                }
 604                        } else
 605                                break;
 606                }
 607                snd_printd("start\n");
 608                /* start the master stream */
 609                snd_card_asihpi_pcm_timer_start(substream);
 610                hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
 611                break;
 612
 613        case SNDRV_PCM_TRIGGER_STOP:
 614                snd_card_asihpi_pcm_timer_stop(substream);
 615                snd_pcm_group_for_each_entry(s, substream) {
 616                        if (snd_pcm_substream_chip(s) != card)
 617                                continue;
 618
 619                        /*? workaround linked streams don't
 620                        transition to SETUP 20070706*/
 621                        s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
 622
 623                        if (card->support_grouping) {
 624                                VPRINTK1("\t_group %dstream %d\n", s->stream,
 625                                        s->number);
 626                                snd_pcm_trigger_done(s, substream);
 627                        } else
 628                                break;
 629                }
 630                snd_printd("stop\n");
 631
 632                /* _prepare and _hwparams reset the stream */
 633                hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
 634                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 635                        hpi_handle_error(
 636                                hpi_outstream_reset(ss, dpcm->h_stream));
 637
 638                if (card->support_grouping)
 639                        hpi_handle_error(hpi_stream_group_reset(ss,
 640                                                dpcm->h_stream));
 641                break;
 642
 643        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 644                snd_printd("pause release\n");
 645                hpi_handle_error(hpi_stream_start(ss, dpcm->h_stream));
 646                snd_card_asihpi_pcm_timer_start(substream);
 647                break;
 648        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 649                snd_printd("pause\n");
 650                snd_card_asihpi_pcm_timer_stop(substream);
 651                hpi_handle_error(hpi_stream_stop(ss, dpcm->h_stream));
 652                break;
 653        default:
 654                snd_printd("\tINVALID\n");
 655                return -EINVAL;
 656        }
 657
 658        return 0;
 659}
 660
 661static int
 662snd_card_asihpi_hw_free(struct snd_pcm_substream *substream)
 663{
 664        struct snd_pcm_runtime *runtime = substream->runtime;
 665        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 666        if (dpcm->hpi_buffer_attached)
 667                hpi_stream_host_buffer_detach(ss, dpcm->h_stream);
 668
 669        snd_pcm_lib_free_pages(substream);
 670        return 0;
 671}
 672
 673static void snd_card_asihpi_runtime_free(struct snd_pcm_runtime *runtime)
 674{
 675        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 676        kfree(dpcm);
 677}
 678
 679/*algorithm outline
 680 Without linking degenerates to getting single stream pos etc
 681 Without mmap 2nd loop degenerates to snd_pcm_period_elapsed
 682*/
 683/*
 684buf_pos=get_buf_pos(s);
 685for_each_linked_stream(s) {
 686        buf_pos=get_buf_pos(s);
 687        min_buf_pos = modulo_min(min_buf_pos, buf_pos, pcm_size)
 688        new_data = min(new_data, calc_new_data(buf_pos,irq_pos)
 689}
 690timer.expires = jiffies + predict_next_period_ready(min_buf_pos);
 691for_each_linked_stream(s) {
 692        s->buf_pos = min_buf_pos;
 693        if (new_data > pcm_count) {
 694                if (mmap) {
 695                        irq_pos = (irq_pos + pcm_count) % pcm_size;
 696                        if (playback) {
 697                                write(pcm_count);
 698                        } else {
 699                                read(pcm_count);
 700                        }
 701                }
 702                snd_pcm_period_elapsed(s);
 703        }
 704}
 705*/
 706
 707/** Minimum of 2 modulo values.  Works correctly when the difference between
 708* the values is less than half the modulus
 709*/
 710static inline unsigned int modulo_min(unsigned int a, unsigned int b,
 711                                        unsigned long int modulus)
 712{
 713        unsigned int result;
 714        if (((a-b) % modulus) < (modulus/2))
 715                result = b;
 716        else
 717                result = a;
 718
 719        return result;
 720}
 721
 722/** Timer function, equivalent to interrupt service routine for cards
 723*/
 724static void snd_card_asihpi_timer_function(unsigned long data)
 725{
 726        struct snd_card_asihpi_pcm *dpcm = (struct snd_card_asihpi_pcm *)data;
 727        struct snd_card_asihpi *card = snd_pcm_substream_chip(dpcm->substream);
 728        struct snd_pcm_runtime *runtime;
 729        struct snd_pcm_substream *s;
 730        unsigned int newdata = 0;
 731        unsigned int buf_pos, min_buf_pos = 0;
 732        unsigned int remdata, xfercount, next_jiffies;
 733        int first = 1;
 734        u16 state;
 735        u32 buffer_size, data_avail, samples_played, aux;
 736
 737        /* find minimum newdata and buffer pos in group */
 738        snd_pcm_group_for_each_entry(s, dpcm->substream) {
 739                struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
 740                runtime = s->runtime;
 741
 742                if (snd_pcm_substream_chip(s) != card)
 743                        continue;
 744
 745                hpi_handle_error(hpi_stream_get_info_ex(ss,
 746                                        ds->h_stream, &state,
 747                                        &buffer_size, &data_avail,
 748                                        &samples_played, &aux));
 749
 750                /* number of bytes in on-card buffer */
 751                runtime->delay = aux;
 752
 753                if (state == HPI_STATE_DRAINED) {
 754                        snd_printd(KERN_WARNING  "outstream %d drained\n",
 755                                        s->number);
 756                        snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
 757                        return;
 758                }
 759
 760                if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 761                        buf_pos = frames_to_bytes(runtime, samples_played);
 762                } else {
 763                        buf_pos = data_avail + ds->pcm_irq_pos;
 764                }
 765
 766                if (first) {
 767                        /* can't statically init min when wrap is involved */
 768                        min_buf_pos = buf_pos;
 769                        newdata = (buf_pos - ds->pcm_irq_pos) % ds->pcm_size;
 770                        first = 0;
 771                } else {
 772                        min_buf_pos =
 773                                modulo_min(min_buf_pos, buf_pos, UINT_MAX+1L);
 774                        newdata = min(
 775                                (buf_pos - ds->pcm_irq_pos) % ds->pcm_size,
 776                                newdata);
 777                }
 778
 779                VPRINTK1("PB timer hw_ptr x%04lX, appl_ptr x%04lX\n",
 780                        (unsigned long)frames_to_bytes(runtime,
 781                                                runtime->status->hw_ptr),
 782                        (unsigned long)frames_to_bytes(runtime,
 783                                                runtime->control->appl_ptr));
 784                VPRINTK1("%d S=%d, irq=%04X, pos=x%04X, left=x%04X,"
 785                        " aux=x%04X space=x%04X\n", s->number,
 786                        state,  ds->pcm_irq_pos, buf_pos, (int)data_avail,
 787                        (int)aux, buffer_size-data_avail);
 788        }
 789
 790        remdata = newdata % dpcm->pcm_count;
 791        xfercount = newdata - remdata; /* a multiple of pcm_count */
 792        next_jiffies = ((dpcm->pcm_count-remdata) * HZ / dpcm->bytes_per_sec)+1;
 793        next_jiffies = max(next_jiffies, 2U * HZ / 1000U);
 794        dpcm->timer.expires = jiffies + next_jiffies;
 795        VPRINTK1("jif %d buf pos x%04X newdata x%04X xc x%04X\n",
 796                        next_jiffies, min_buf_pos, newdata, xfercount);
 797
 798        snd_pcm_group_for_each_entry(s, dpcm->substream) {
 799                struct snd_card_asihpi_pcm *ds = s->runtime->private_data;
 800                ds->pcm_buf_pos = min_buf_pos;
 801
 802                if (xfercount) {
 803                        if (card->support_mmap) {
 804                                ds->pcm_irq_pos = ds->pcm_irq_pos + xfercount;
 805                                if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 806                                        VPRINTK2("write OS%d x%04x\n",
 807                                                        s->number,
 808                                                        ds->pcm_count);
 809                                        hpi_handle_error(
 810                                                hpi_outstream_write_buf(
 811                                                        ss, ds->h_stream,
 812                                                        &s->runtime->
 813                                                                dma_area[0],
 814                                                        xfercount,
 815                                                        &ds->format));
 816                                } else {
 817                                        VPRINTK2("read IS%d x%04x\n",
 818                                                s->number,
 819                                                dpcm->pcm_count);
 820                                        hpi_handle_error(
 821                                                hpi_instream_read_buf(
 822                                                        ss, ds->h_stream,
 823                                                        NULL, xfercount));
 824                                }
 825                        } /* else R/W will be handled by read/write callbacks */
 826                        snd_pcm_period_elapsed(s);
 827                }
 828        }
 829
 830        if (dpcm->respawn_timer)
 831                add_timer(&dpcm->timer);
 832}
 833
 834/***************************** PLAYBACK OPS ****************/
 835static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream,
 836                                          unsigned int cmd, void *arg)
 837{
 838        /* snd_printd(KERN_INFO "Playback ioctl %d\n", cmd); */
 839        return snd_pcm_lib_ioctl(substream, cmd, arg);
 840}
 841
 842static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream *
 843                                            substream)
 844{
 845        struct snd_pcm_runtime *runtime = substream->runtime;
 846        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 847
 848        snd_printd(KERN_INFO "playback prepare %d\n", substream->number);
 849
 850        hpi_handle_error(hpi_outstream_reset(ss, dpcm->h_stream));
 851        dpcm->pcm_irq_pos = 0;
 852        dpcm->pcm_buf_pos = 0;
 853
 854        return 0;
 855}
 856
 857static snd_pcm_uframes_t
 858snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream)
 859{
 860        struct snd_pcm_runtime *runtime = substream->runtime;
 861        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
 862        snd_pcm_uframes_t ptr;
 863
 864        u32 samples_played;
 865        u16 err;
 866
 867        if (!snd_pcm_stream_linked(substream)) {
 868                /* NOTE, can use samples played for playback position here and
 869                * in timer fn because it LAGS the actual read pointer, and is a
 870                * better representation of actual playout position
 871                */
 872                err = hpi_outstream_get_info_ex(ss, dpcm->h_stream, NULL,
 873                                        NULL, NULL,
 874                                        &samples_played, NULL);
 875                hpi_handle_error(err);
 876
 877                dpcm->pcm_buf_pos = frames_to_bytes(runtime, samples_played);
 878        }
 879        /* else must return most conservative value found in timer func
 880         * by looping over all streams
 881         */
 882
 883        ptr = bytes_to_frames(runtime, dpcm->pcm_buf_pos  % dpcm->pcm_size);
 884        VPRINTK2("playback_pointer=%04ld\n", (unsigned long)ptr);
 885        return ptr;
 886}
 887
 888static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi,
 889                                                u32 h_stream,
 890                                                struct snd_pcm_hardware *pcmhw)
 891{
 892        struct hpi_format hpi_format;
 893        u16 format;
 894        u16 err;
 895        u32 h_control;
 896        u32 sample_rate = 48000;
 897
 898        /* on cards without SRC, must query at valid rate,
 899        * maybe set by external sync
 900        */
 901        err = hpi_mixer_get_control(ss, asihpi->h_mixer,
 902                                  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
 903                                  HPI_CONTROL_SAMPLECLOCK, &h_control);
 904
 905        if (!err)
 906                err = hpi_sample_clock_get_sample_rate(ss, h_control,
 907                                &sample_rate);
 908
 909        for (format = HPI_FORMAT_PCM8_UNSIGNED;
 910             format <= HPI_FORMAT_PCM24_SIGNED; format++) {
 911                err = hpi_format_create(&hpi_format,
 912                                        2, format, sample_rate, 128000, 0);
 913                if (!err)
 914                        err = hpi_outstream_query_format(ss, h_stream,
 915                                                        &hpi_format);
 916                if (!err && (hpi_to_alsa_formats[format] != -1))
 917                        pcmhw->formats |=
 918                                (1ULL << hpi_to_alsa_formats[format]);
 919        }
 920}
 921
 922static struct snd_pcm_hardware snd_card_asihpi_playback = {
 923        .channels_min = 1,
 924        .channels_max = 2,
 925        .buffer_bytes_max = BUFFER_BYTES_MAX,
 926        .period_bytes_min = PERIOD_BYTES_MIN,
 927        .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
 928        .periods_min = PERIODS_MIN,
 929        .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
 930        .fifo_size = 0,
 931};
 932
 933static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream)
 934{
 935        struct snd_pcm_runtime *runtime = substream->runtime;
 936        struct snd_card_asihpi_pcm *dpcm;
 937        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
 938        int err;
 939
 940        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
 941        if (dpcm == NULL)
 942                return -ENOMEM;
 943
 944        err =
 945            hpi_outstream_open(ss, card->adapter_index,
 946                              substream->number, &dpcm->h_stream);
 947        hpi_handle_error(err);
 948        if (err)
 949                kfree(dpcm);
 950        if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
 951                return -EBUSY;
 952        if (err)
 953                return -EIO;
 954
 955        /*? also check ASI5000 samplerate source
 956            If external, only support external rate.
 957            If internal and other stream playing, cant switch
 958        */
 959
 960        init_timer(&dpcm->timer);
 961        dpcm->timer.data = (unsigned long) dpcm;
 962        dpcm->timer.function = snd_card_asihpi_timer_function;
 963        dpcm->substream = substream;
 964        runtime->private_data = dpcm;
 965        runtime->private_free = snd_card_asihpi_runtime_free;
 966
 967        snd_card_asihpi_playback.channels_max = card->out_max_chans;
 968        /*?snd_card_asihpi_playback.period_bytes_min =
 969        card->out_max_chans * 4096; */
 970
 971        snd_card_asihpi_playback_format(card, dpcm->h_stream,
 972                                        &snd_card_asihpi_playback);
 973
 974        snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_playback);
 975
 976        snd_card_asihpi_playback.info = SNDRV_PCM_INFO_INTERLEAVED |
 977                                        SNDRV_PCM_INFO_DOUBLE |
 978                                        SNDRV_PCM_INFO_BATCH |
 979                                        SNDRV_PCM_INFO_BLOCK_TRANSFER |
 980                                        SNDRV_PCM_INFO_PAUSE;
 981
 982        if (card->support_mmap)
 983                snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP |
 984                                                SNDRV_PCM_INFO_MMAP_VALID;
 985
 986        if (card->support_grouping)
 987                snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START;
 988
 989        /* struct is copied, so can create initializer dynamically */
 990        runtime->hw = snd_card_asihpi_playback;
 991
 992        if (card->support_mmap)
 993                err = snd_pcm_hw_constraint_pow2(runtime, 0,
 994                                        SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
 995        if (err < 0)
 996                return err;
 997
 998        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
 999                card->update_interval_frames);
1000        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1001                card->update_interval_frames * 4, UINT_MAX);
1002
1003        snd_pcm_set_sync(substream);
1004
1005        snd_printd(KERN_INFO "playback open\n");
1006
1007        return 0;
1008}
1009
1010static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream)
1011{
1012        struct snd_pcm_runtime *runtime = substream->runtime;
1013        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1014
1015        hpi_handle_error(hpi_outstream_close(ss, dpcm->h_stream));
1016        snd_printd(KERN_INFO "playback close\n");
1017
1018        return 0;
1019}
1020
1021static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream,
1022                                        int channel,
1023                                        snd_pcm_uframes_t pos,
1024                                        void __user *src,
1025                                        snd_pcm_uframes_t count)
1026{
1027        struct snd_pcm_runtime *runtime = substream->runtime;
1028        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1029        unsigned int len;
1030
1031        len = frames_to_bytes(runtime, count);
1032
1033        if (copy_from_user(runtime->dma_area, src, len))
1034                return -EFAULT;
1035
1036        VPRINTK2(KERN_DEBUG "playback copy%d %u bytes\n",
1037                        substream->number, len);
1038
1039        hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1040                                runtime->dma_area, len, &dpcm->format));
1041
1042        return 0;
1043}
1044
1045static int snd_card_asihpi_playback_silence(struct snd_pcm_substream *
1046                                            substream, int channel,
1047                                            snd_pcm_uframes_t pos,
1048                                            snd_pcm_uframes_t count)
1049{
1050        unsigned int len;
1051        struct snd_pcm_runtime *runtime = substream->runtime;
1052        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1053
1054        len = frames_to_bytes(runtime, count);
1055        snd_printd(KERN_INFO "playback silence  %u bytes\n", len);
1056
1057        memset(runtime->dma_area, 0, len);
1058        hpi_handle_error(hpi_outstream_write_buf(ss, dpcm->h_stream,
1059                                runtime->dma_area, len, &dpcm->format));
1060        return 0;
1061}
1062
1063static struct snd_pcm_ops snd_card_asihpi_playback_ops = {
1064        .open = snd_card_asihpi_playback_open,
1065        .close = snd_card_asihpi_playback_close,
1066        .ioctl = snd_card_asihpi_playback_ioctl,
1067        .hw_params = snd_card_asihpi_pcm_hw_params,
1068        .hw_free = snd_card_asihpi_hw_free,
1069        .prepare = snd_card_asihpi_playback_prepare,
1070        .trigger = snd_card_asihpi_trigger,
1071        .pointer = snd_card_asihpi_playback_pointer,
1072        .copy = snd_card_asihpi_playback_copy,
1073        .silence = snd_card_asihpi_playback_silence,
1074};
1075
1076static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = {
1077        .open = snd_card_asihpi_playback_open,
1078        .close = snd_card_asihpi_playback_close,
1079        .ioctl = snd_card_asihpi_playback_ioctl,
1080        .hw_params = snd_card_asihpi_pcm_hw_params,
1081        .hw_free = snd_card_asihpi_hw_free,
1082        .prepare = snd_card_asihpi_playback_prepare,
1083        .trigger = snd_card_asihpi_trigger,
1084        .pointer = snd_card_asihpi_playback_pointer,
1085};
1086
1087/***************************** CAPTURE OPS ****************/
1088static snd_pcm_uframes_t
1089snd_card_asihpi_capture_pointer(struct snd_pcm_substream *substream)
1090{
1091        struct snd_pcm_runtime *runtime = substream->runtime;
1092        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1093
1094        VPRINTK2("capture pointer %d=%d\n",
1095                        substream->number, dpcm->pcm_buf_pos);
1096        /* NOTE Unlike playback can't use actual dwSamplesPlayed
1097                for the capture position, because those samples aren't yet in
1098                the local buffer available for reading.
1099        */
1100        return bytes_to_frames(runtime, dpcm->pcm_buf_pos % dpcm->pcm_size);
1101}
1102
1103static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream,
1104                                         unsigned int cmd, void *arg)
1105{
1106        return snd_pcm_lib_ioctl(substream, cmd, arg);
1107}
1108
1109static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream)
1110{
1111        struct snd_pcm_runtime *runtime = substream->runtime;
1112        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1113
1114        hpi_handle_error(hpi_instream_reset(ss, dpcm->h_stream));
1115        dpcm->pcm_irq_pos = 0;
1116        dpcm->pcm_buf_pos = 0;
1117
1118        snd_printd("capture prepare %d\n", substream->number);
1119        return 0;
1120}
1121
1122
1123
1124static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi,
1125                                        u32 h_stream,
1126                                         struct snd_pcm_hardware *pcmhw)
1127{
1128  struct hpi_format hpi_format;
1129        u16 format;
1130        u16 err;
1131        u32 h_control;
1132        u32 sample_rate = 48000;
1133
1134        /* on cards without SRC, must query at valid rate,
1135                maybe set by external sync */
1136        err = hpi_mixer_get_control(ss, asihpi->h_mixer,
1137                                  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
1138                                  HPI_CONTROL_SAMPLECLOCK, &h_control);
1139
1140        if (!err)
1141                err = hpi_sample_clock_get_sample_rate(ss, h_control,
1142                        &sample_rate);
1143
1144        for (format = HPI_FORMAT_PCM8_UNSIGNED;
1145                format <= HPI_FORMAT_PCM24_SIGNED; format++) {
1146
1147                err = hpi_format_create(&hpi_format, 2, format,
1148                                sample_rate, 128000, 0);
1149                if (!err)
1150                        err = hpi_instream_query_format(ss, h_stream,
1151                                            &hpi_format);
1152                if (!err)
1153                        pcmhw->formats |=
1154                                (1ULL << hpi_to_alsa_formats[format]);
1155        }
1156}
1157
1158
1159static struct snd_pcm_hardware snd_card_asihpi_capture = {
1160        .channels_min = 1,
1161        .channels_max = 2,
1162        .buffer_bytes_max = BUFFER_BYTES_MAX,
1163        .period_bytes_min = PERIOD_BYTES_MIN,
1164        .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN,
1165        .periods_min = PERIODS_MIN,
1166        .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN,
1167        .fifo_size = 0,
1168};
1169
1170static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream)
1171{
1172        struct snd_pcm_runtime *runtime = substream->runtime;
1173        struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
1174        struct snd_card_asihpi_pcm *dpcm;
1175        int err;
1176
1177        dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
1178        if (dpcm == NULL)
1179                return -ENOMEM;
1180
1181        snd_printd("hpi_instream_open adapter %d stream %d\n",
1182                   card->adapter_index, substream->number);
1183
1184        err = hpi_handle_error(
1185            hpi_instream_open(ss, card->adapter_index,
1186                             substream->number, &dpcm->h_stream));
1187        if (err)
1188                kfree(dpcm);
1189        if (err == HPI_ERROR_OBJ_ALREADY_OPEN)
1190                return -EBUSY;
1191        if (err)
1192                return -EIO;
1193
1194
1195        init_timer(&dpcm->timer);
1196        dpcm->timer.data = (unsigned long) dpcm;
1197        dpcm->timer.function = snd_card_asihpi_timer_function;
1198        dpcm->substream = substream;
1199        runtime->private_data = dpcm;
1200        runtime->private_free = snd_card_asihpi_runtime_free;
1201
1202        snd_card_asihpi_capture.channels_max = card->in_max_chans;
1203        snd_card_asihpi_capture_format(card, dpcm->h_stream,
1204                                       &snd_card_asihpi_capture);
1205        snd_card_asihpi_pcm_samplerates(card,  &snd_card_asihpi_capture);
1206        snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED;
1207
1208        if (card->support_mmap)
1209                snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP |
1210                                                SNDRV_PCM_INFO_MMAP_VALID;
1211
1212        runtime->hw = snd_card_asihpi_capture;
1213
1214        if (card->support_mmap)
1215                err = snd_pcm_hw_constraint_pow2(runtime, 0,
1216                                        SNDRV_PCM_HW_PARAM_BUFFER_BYTES);
1217        if (err < 0)
1218                return err;
1219
1220        snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1221                card->update_interval_frames);
1222        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
1223                card->update_interval_frames * 2, UINT_MAX);
1224
1225        snd_pcm_set_sync(substream);
1226
1227        return 0;
1228}
1229
1230static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream)
1231{
1232        struct snd_card_asihpi_pcm *dpcm = substream->runtime->private_data;
1233
1234        hpi_handle_error(hpi_instream_close(ss, dpcm->h_stream));
1235        return 0;
1236}
1237
1238static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream,
1239                                int channel, snd_pcm_uframes_t pos,
1240                                void __user *dst, snd_pcm_uframes_t count)
1241{
1242        struct snd_pcm_runtime *runtime = substream->runtime;
1243        struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
1244        u32 data_size;
1245
1246        data_size = frames_to_bytes(runtime, count);
1247
1248        VPRINTK2("capture copy%d %d bytes\n", substream->number, data_size);
1249        hpi_handle_error(hpi_instream_read_buf(ss, dpcm->h_stream,
1250                                runtime->dma_area, data_size));
1251
1252        /* Used by capture_pointer */
1253        dpcm->pcm_irq_pos = dpcm->pcm_irq_pos + data_size;
1254
1255        if (copy_to_user(dst, runtime->dma_area, data_size))
1256                return -EFAULT;
1257
1258        return 0;
1259}
1260
1261static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = {
1262        .open = snd_card_asihpi_capture_open,
1263        .close = snd_card_asihpi_capture_close,
1264        .ioctl = snd_card_asihpi_capture_ioctl,
1265        .hw_params = snd_card_asihpi_pcm_hw_params,
1266        .hw_free = snd_card_asihpi_hw_free,
1267        .prepare = snd_card_asihpi_capture_prepare,
1268        .trigger = snd_card_asihpi_trigger,
1269        .pointer = snd_card_asihpi_capture_pointer,
1270};
1271
1272static struct snd_pcm_ops snd_card_asihpi_capture_ops = {
1273        .open = snd_card_asihpi_capture_open,
1274        .close = snd_card_asihpi_capture_close,
1275        .ioctl = snd_card_asihpi_capture_ioctl,
1276        .hw_params = snd_card_asihpi_pcm_hw_params,
1277        .hw_free = snd_card_asihpi_hw_free,
1278        .prepare = snd_card_asihpi_capture_prepare,
1279        .trigger = snd_card_asihpi_trigger,
1280        .pointer = snd_card_asihpi_capture_pointer,
1281        .copy = snd_card_asihpi_capture_copy
1282};
1283
1284static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi,
1285                                      int device, int substreams)
1286{
1287        struct snd_pcm *pcm;
1288        int err;
1289
1290        err = snd_pcm_new(asihpi->card, "asihpi PCM", device,
1291                         asihpi->num_outstreams, asihpi->num_instreams,
1292                         &pcm);
1293        if (err < 0)
1294                return err;
1295        /* pointer to ops struct is stored, dont change ops afterwards! */
1296        if (asihpi->support_mmap) {
1297                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1298                                &snd_card_asihpi_playback_mmap_ops);
1299                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1300                                &snd_card_asihpi_capture_mmap_ops);
1301        } else {
1302                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1303                                &snd_card_asihpi_playback_ops);
1304                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1305                                &snd_card_asihpi_capture_ops);
1306        }
1307
1308        pcm->private_data = asihpi;
1309        pcm->info_flags = 0;
1310        strcpy(pcm->name, "asihpi PCM");
1311
1312        /*? do we want to emulate MMAP for non-BBM cards?
1313        Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */
1314        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1315                                                snd_dma_pci_data(asihpi->pci),
1316                                                64*1024, BUFFER_BYTES_MAX);
1317
1318        return 0;
1319}
1320
1321/***************************** MIXER CONTROLS ****************/
1322struct hpi_control {
1323        u32 h_control;
1324        u16 control_type;
1325        u16 src_node_type;
1326        u16 src_node_index;
1327        u16 dst_node_type;
1328        u16 dst_node_index;
1329        u16 band;
1330        char name[44]; /* copied to snd_ctl_elem_id.name[44]; */
1331};
1332
1333static char *asihpi_tuner_band_names[] =
1334{
1335        "invalid",
1336        "AM",
1337        "FM mono",
1338        "TV NTSC-M",
1339        "FM stereo",
1340        "AUX",
1341        "TV PAL BG",
1342        "TV PAL I",
1343        "TV PAL DK",
1344        "TV SECAM",
1345};
1346
1347compile_time_assert(
1348        (ARRAY_SIZE(asihpi_tuner_band_names) ==
1349                (HPI_TUNER_BAND_LAST+1)),
1350        assert_tuner_band_names_size);
1351
1352#if ASI_STYLE_NAMES
1353static char *asihpi_src_names[] =
1354{
1355        "no source",
1356        "outstream",
1357        "line_in",
1358        "aes_in",
1359        "tuner",
1360        "RF",
1361        "clock",
1362        "bitstr",
1363        "mic",
1364        "cobranet",
1365        "analog_in",
1366        "adapter",
1367};
1368#else
1369static char *asihpi_src_names[] =
1370{
1371        "no source",
1372        "PCM playback",
1373        "line in",
1374        "digital in",
1375        "tuner",
1376        "RF",
1377        "clock",
1378        "bitstream",
1379        "mic",
1380        "cobranet in",
1381        "analog in",
1382        "adapter",
1383};
1384#endif
1385
1386compile_time_assert(
1387        (ARRAY_SIZE(asihpi_src_names) ==
1388                (HPI_SOURCENODE_LAST_INDEX-HPI_SOURCENODE_NONE+1)),
1389        assert_src_names_size);
1390
1391#if ASI_STYLE_NAMES
1392static char *asihpi_dst_names[] =
1393{
1394        "no destination",
1395        "instream",
1396        "line_out",
1397        "aes_out",
1398        "RF",
1399        "speaker" ,
1400        "cobranet",
1401        "analog_out",
1402};
1403#else
1404static char *asihpi_dst_names[] =
1405{
1406        "no destination",
1407        "PCM capture",
1408        "line out",
1409        "digital out",
1410        "RF",
1411        "speaker",
1412        "cobranet out",
1413        "analog out"
1414};
1415#endif
1416
1417compile_time_assert(
1418        (ARRAY_SIZE(asihpi_dst_names) ==
1419                (HPI_DESTNODE_LAST_INDEX-HPI_DESTNODE_NONE+1)),
1420        assert_dst_names_size);
1421
1422static inline int ctl_add(struct snd_card *card, struct snd_kcontrol_new *ctl,
1423                                struct snd_card_asihpi *asihpi)
1424{
1425        int err;
1426
1427        err = snd_ctl_add(card, snd_ctl_new1(ctl, asihpi));
1428        if (err < 0)
1429                return err;
1430        else if (mixer_dump)
1431                snd_printk(KERN_INFO "added %s(%d)\n", ctl->name, ctl->index);
1432
1433        return 0;
1434}
1435
1436/* Convert HPI control name and location into ALSA control name */
1437static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
1438                                struct hpi_control *hpi_ctl,
1439                                char *name)
1440{
1441        memset(snd_control, 0, sizeof(*snd_control));
1442        snd_control->name = hpi_ctl->name;
1443        snd_control->private_value = hpi_ctl->h_control;
1444        snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1445        snd_control->index = 0;
1446
1447        if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
1448                sprintf(hpi_ctl->name, "%s%d to %s%d %s",
1449                        asihpi_src_names[hpi_ctl->src_node_type],
1450                        hpi_ctl->src_node_index,
1451                        asihpi_dst_names[hpi_ctl->dst_node_type],
1452                        hpi_ctl->dst_node_index,
1453                        name);
1454        else if (hpi_ctl->dst_node_type) {
1455                sprintf(hpi_ctl->name, "%s%d %s",
1456                asihpi_dst_names[hpi_ctl->dst_node_type],
1457                hpi_ctl->dst_node_index,
1458                name);
1459        } else {
1460                sprintf(hpi_ctl->name, "%s%d %s",
1461                asihpi_src_names[hpi_ctl->src_node_type],
1462                hpi_ctl->src_node_index,
1463                name);
1464        }
1465}
1466
1467/*------------------------------------------------------------
1468   Volume controls
1469 ------------------------------------------------------------*/
1470#define VOL_STEP_mB 1
1471static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol,
1472                                  struct snd_ctl_elem_info *uinfo)
1473{
1474        u32 h_control = kcontrol->private_value;
1475        u16 err;
1476        /* native gains are in millibels */
1477        short min_gain_mB;
1478        short max_gain_mB;
1479        short step_gain_mB;
1480
1481        err = hpi_volume_query_range(ss, h_control,
1482                        &min_gain_mB, &max_gain_mB, &step_gain_mB);
1483        if (err) {
1484                max_gain_mB = 0;
1485                min_gain_mB = -10000;
1486                step_gain_mB = VOL_STEP_mB;
1487        }
1488
1489        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1490        uinfo->count = 2;
1491        uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB;
1492        uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB;
1493        uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB;
1494        return 0;
1495}
1496
1497static int snd_asihpi_volume_get(struct snd_kcontrol *kcontrol,
1498                                 struct snd_ctl_elem_value *ucontrol)
1499{
1500        u32 h_control = kcontrol->private_value;
1501        short an_gain_mB[HPI_MAX_CHANNELS];
1502
1503        hpi_handle_error(hpi_volume_get_gain(ss, h_control, an_gain_mB));
1504        ucontrol->value.integer.value[0] = an_gain_mB[0] / VOL_STEP_mB;
1505        ucontrol->value.integer.value[1] = an_gain_mB[1] / VOL_STEP_mB;
1506
1507        return 0;
1508}
1509
1510static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
1511                                 struct snd_ctl_elem_value *ucontrol)
1512{
1513        int change;
1514        u32 h_control = kcontrol->private_value;
1515        short an_gain_mB[HPI_MAX_CHANNELS];
1516
1517        an_gain_mB[0] =
1518            (ucontrol->value.integer.value[0]) * VOL_STEP_mB;
1519        an_gain_mB[1] =
1520            (ucontrol->value.integer.value[1]) * VOL_STEP_mB;
1521        /*  change = asihpi->mixer_volume[addr][0] != left ||
1522           asihpi->mixer_volume[addr][1] != right;
1523         */
1524        change = 1;
1525        hpi_handle_error(hpi_volume_set_gain(ss, h_control, an_gain_mB));
1526        return change;
1527}
1528
1529static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
1530
1531static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
1532                                        struct hpi_control *hpi_ctl)
1533{
1534        struct snd_card *card = asihpi->card;
1535        struct snd_kcontrol_new snd_control;
1536
1537        asihpi_ctl_init(&snd_control, hpi_ctl, "volume");
1538        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1539                                SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1540        snd_control.info = snd_asihpi_volume_info;
1541        snd_control.get = snd_asihpi_volume_get;
1542        snd_control.put = snd_asihpi_volume_put;
1543        snd_control.tlv.p = db_scale_100;
1544
1545        return ctl_add(card, &snd_control, asihpi);
1546}
1547
1548/*------------------------------------------------------------
1549   Level controls
1550 ------------------------------------------------------------*/
1551static int snd_asihpi_level_info(struct snd_kcontrol *kcontrol,
1552                                 struct snd_ctl_elem_info *uinfo)
1553{
1554        u32 h_control = kcontrol->private_value;
1555        u16 err;
1556        short min_gain_mB;
1557        short max_gain_mB;
1558        short step_gain_mB;
1559
1560        err =
1561            hpi_level_query_range(ss, h_control, &min_gain_mB,
1562                               &max_gain_mB, &step_gain_mB);
1563        if (err) {
1564                max_gain_mB = 2400;
1565                min_gain_mB = -1000;
1566                step_gain_mB = 100;
1567        }
1568
1569        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1570        uinfo->count = 2;
1571        uinfo->value.integer.min = min_gain_mB / HPI_UNITS_PER_dB;
1572        uinfo->value.integer.max = max_gain_mB / HPI_UNITS_PER_dB;
1573        uinfo->value.integer.step = step_gain_mB / HPI_UNITS_PER_dB;
1574        return 0;
1575}
1576
1577static int snd_asihpi_level_get(struct snd_kcontrol *kcontrol,
1578                                struct snd_ctl_elem_value *ucontrol)
1579{
1580        u32 h_control = kcontrol->private_value;
1581        short an_gain_mB[HPI_MAX_CHANNELS];
1582
1583        hpi_handle_error(hpi_level_get_gain(ss, h_control, an_gain_mB));
1584        ucontrol->value.integer.value[0] =
1585            an_gain_mB[0] / HPI_UNITS_PER_dB;
1586        ucontrol->value.integer.value[1] =
1587            an_gain_mB[1] / HPI_UNITS_PER_dB;
1588
1589        return 0;
1590}
1591
1592static int snd_asihpi_level_put(struct snd_kcontrol *kcontrol,
1593                                struct snd_ctl_elem_value *ucontrol)
1594{
1595        int change;
1596        u32 h_control = kcontrol->private_value;
1597        short an_gain_mB[HPI_MAX_CHANNELS];
1598
1599        an_gain_mB[0] =
1600            (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1601        an_gain_mB[1] =
1602            (ucontrol->value.integer.value[1]) * HPI_UNITS_PER_dB;
1603        /*  change = asihpi->mixer_level[addr][0] != left ||
1604           asihpi->mixer_level[addr][1] != right;
1605         */
1606        change = 1;
1607        hpi_handle_error(hpi_level_set_gain(ss, h_control, an_gain_mB));
1608        return change;
1609}
1610
1611static const DECLARE_TLV_DB_SCALE(db_scale_level, -1000, 100, 0);
1612
1613static int __devinit snd_asihpi_level_add(struct snd_card_asihpi *asihpi,
1614                                        struct hpi_control *hpi_ctl)
1615{
1616        struct snd_card *card = asihpi->card;
1617        struct snd_kcontrol_new snd_control;
1618
1619        /* can't use 'volume' cos some nodes have volume as well */
1620        asihpi_ctl_init(&snd_control, hpi_ctl, "level");
1621        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1622                                SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1623        snd_control.info = snd_asihpi_level_info;
1624        snd_control.get = snd_asihpi_level_get;
1625        snd_control.put = snd_asihpi_level_put;
1626        snd_control.tlv.p = db_scale_level;
1627
1628        return ctl_add(card, &snd_control, asihpi);
1629}
1630
1631/*------------------------------------------------------------
1632   AESEBU controls
1633 ------------------------------------------------------------*/
1634
1635/* AESEBU format */
1636static char *asihpi_aesebu_format_names[] =
1637{
1638        "N/A",
1639        "S/PDIF",
1640        "AES/EBU",
1641};
1642
1643static int snd_asihpi_aesebu_format_info(struct snd_kcontrol *kcontrol,
1644                                  struct snd_ctl_elem_info *uinfo)
1645{
1646        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1647        uinfo->count = 1;
1648        uinfo->value.enumerated.items = 3;
1649
1650        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1651                uinfo->value.enumerated.item =
1652                        uinfo->value.enumerated.items - 1;
1653
1654        strcpy(uinfo->value.enumerated.name,
1655                asihpi_aesebu_format_names[uinfo->value.enumerated.item]);
1656
1657        return 0;
1658}
1659
1660static int snd_asihpi_aesebu_format_get(struct snd_kcontrol *kcontrol,
1661                        struct snd_ctl_elem_value *ucontrol,
1662                        u16 (*func)(const struct hpi_hsubsys *, u32, u16 *))
1663{
1664        u32 h_control = kcontrol->private_value;
1665        u16 source, err;
1666
1667        err = func(ss, h_control, &source);
1668
1669        /* default to N/A */
1670        ucontrol->value.enumerated.item[0] = 0;
1671        /* return success but set the control to N/A */
1672        if (err)
1673                return 0;
1674        if (source == HPI_AESEBU_FORMAT_SPDIF)
1675                ucontrol->value.enumerated.item[0] = 1;
1676        if (source == HPI_AESEBU_FORMAT_AESEBU)
1677                ucontrol->value.enumerated.item[0] = 2;
1678
1679        return 0;
1680}
1681
1682static int snd_asihpi_aesebu_format_put(struct snd_kcontrol *kcontrol,
1683                        struct snd_ctl_elem_value *ucontrol,
1684                         u16 (*func)(const struct hpi_hsubsys *, u32, u16))
1685{
1686        u32 h_control = kcontrol->private_value;
1687
1688        /* default to S/PDIF */
1689        u16 source = HPI_AESEBU_FORMAT_SPDIF;
1690
1691        if (ucontrol->value.enumerated.item[0] == 1)
1692                source = HPI_AESEBU_FORMAT_SPDIF;
1693        if (ucontrol->value.enumerated.item[0] == 2)
1694                source = HPI_AESEBU_FORMAT_AESEBU;
1695
1696        if (func(ss, h_control, source) != 0)
1697                return -EINVAL;
1698
1699        return 1;
1700}
1701
1702static int snd_asihpi_aesebu_rx_format_get(struct snd_kcontrol *kcontrol,
1703                                 struct snd_ctl_elem_value *ucontrol) {
1704        return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1705                                        HPI_AESEBU__receiver_get_format);
1706}
1707
1708static int snd_asihpi_aesebu_rx_format_put(struct snd_kcontrol *kcontrol,
1709                                 struct snd_ctl_elem_value *ucontrol) {
1710        return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1711                                        HPI_AESEBU__receiver_set_format);
1712}
1713
1714static int snd_asihpi_aesebu_rxstatus_info(struct snd_kcontrol *kcontrol,
1715                                  struct snd_ctl_elem_info *uinfo)
1716{
1717        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1718        uinfo->count = 1;
1719
1720        uinfo->value.integer.min = 0;
1721        uinfo->value.integer.max = 0X1F;
1722        uinfo->value.integer.step = 1;
1723
1724        return 0;
1725}
1726
1727static int snd_asihpi_aesebu_rxstatus_get(struct snd_kcontrol *kcontrol,
1728                                 struct snd_ctl_elem_value *ucontrol) {
1729
1730        u32 h_control = kcontrol->private_value;
1731        u16 status;
1732
1733        hpi_handle_error(HPI_AESEBU__receiver_get_error_status(
1734                                ss, h_control, &status));
1735        ucontrol->value.integer.value[0] = status;
1736        return 0;
1737}
1738
1739static int __devinit snd_asihpi_aesebu_rx_add(struct snd_card_asihpi *asihpi,
1740                                        struct hpi_control *hpi_ctl)
1741{
1742        struct snd_card *card = asihpi->card;
1743        struct snd_kcontrol_new snd_control;
1744
1745        asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1746        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1747        snd_control.info = snd_asihpi_aesebu_format_info;
1748        snd_control.get = snd_asihpi_aesebu_rx_format_get;
1749        snd_control.put = snd_asihpi_aesebu_rx_format_put;
1750
1751
1752        if (ctl_add(card, &snd_control, asihpi) < 0)
1753                return -EINVAL;
1754
1755        asihpi_ctl_init(&snd_control, hpi_ctl, "status");
1756        snd_control.access =
1757            SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
1758        snd_control.info = snd_asihpi_aesebu_rxstatus_info;
1759        snd_control.get = snd_asihpi_aesebu_rxstatus_get;
1760
1761        return ctl_add(card, &snd_control, asihpi);
1762}
1763
1764static int snd_asihpi_aesebu_tx_format_get(struct snd_kcontrol *kcontrol,
1765                                 struct snd_ctl_elem_value *ucontrol) {
1766        return snd_asihpi_aesebu_format_get(kcontrol, ucontrol,
1767                                        HPI_AESEBU__transmitter_get_format);
1768}
1769
1770static int snd_asihpi_aesebu_tx_format_put(struct snd_kcontrol *kcontrol,
1771                                 struct snd_ctl_elem_value *ucontrol) {
1772        return snd_asihpi_aesebu_format_put(kcontrol, ucontrol,
1773                                        HPI_AESEBU__transmitter_set_format);
1774}
1775
1776
1777static int __devinit snd_asihpi_aesebu_tx_add(struct snd_card_asihpi *asihpi,
1778                                        struct hpi_control *hpi_ctl)
1779{
1780        struct snd_card *card = asihpi->card;
1781        struct snd_kcontrol_new snd_control;
1782
1783        asihpi_ctl_init(&snd_control, hpi_ctl, "format");
1784        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1785        snd_control.info = snd_asihpi_aesebu_format_info;
1786        snd_control.get = snd_asihpi_aesebu_tx_format_get;
1787        snd_control.put = snd_asihpi_aesebu_tx_format_put;
1788
1789        return ctl_add(card, &snd_control, asihpi);
1790}
1791
1792/*------------------------------------------------------------
1793   Tuner controls
1794 ------------------------------------------------------------*/
1795
1796/* Gain */
1797
1798static int snd_asihpi_tuner_gain_info(struct snd_kcontrol *kcontrol,
1799                                  struct snd_ctl_elem_info *uinfo)
1800{
1801        u32 h_control = kcontrol->private_value;
1802        u16 err;
1803        short idx;
1804        u16 gain_range[3];
1805
1806        for (idx = 0; idx < 3; idx++) {
1807                err = hpi_tuner_query_gain(ss, h_control,
1808                                          idx, &gain_range[idx]);
1809                if (err != 0)
1810                        return err;
1811        }
1812
1813        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1814        uinfo->count = 1;
1815        uinfo->value.integer.min = ((int)gain_range[0]) / HPI_UNITS_PER_dB;
1816        uinfo->value.integer.max = ((int)gain_range[1]) / HPI_UNITS_PER_dB;
1817        uinfo->value.integer.step = ((int) gain_range[2]) / HPI_UNITS_PER_dB;
1818        return 0;
1819}
1820
1821static int snd_asihpi_tuner_gain_get(struct snd_kcontrol *kcontrol,
1822                                 struct snd_ctl_elem_value *ucontrol)
1823{
1824        /*
1825        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1826        */
1827        u32 h_control = kcontrol->private_value;
1828        short gain;
1829
1830        hpi_handle_error(hpi_tuner_get_gain(ss, h_control, &gain));
1831        ucontrol->value.integer.value[0] = gain / HPI_UNITS_PER_dB;
1832
1833        return 0;
1834}
1835
1836static int snd_asihpi_tuner_gain_put(struct snd_kcontrol *kcontrol,
1837                                 struct snd_ctl_elem_value *ucontrol)
1838{
1839        /*
1840        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1841        */
1842        u32 h_control = kcontrol->private_value;
1843        short gain;
1844
1845        gain = (ucontrol->value.integer.value[0]) * HPI_UNITS_PER_dB;
1846        hpi_handle_error(hpi_tuner_set_gain(ss, h_control, gain));
1847
1848        return 1;
1849}
1850
1851/* Band  */
1852
1853static int asihpi_tuner_band_query(struct snd_kcontrol *kcontrol,
1854                                        u16 *band_list, u32 len) {
1855        u32 h_control = kcontrol->private_value;
1856        u16 err = 0;
1857        u32 i;
1858
1859        for (i = 0; i < len; i++) {
1860                err = hpi_tuner_query_band(ss,
1861                                h_control, i, &band_list[i]);
1862                if (err != 0)
1863                        break;
1864        }
1865
1866        if (err && (err != HPI_ERROR_INVALID_OBJ_INDEX))
1867                return -EIO;
1868
1869        return i;
1870}
1871
1872static int snd_asihpi_tuner_band_info(struct snd_kcontrol *kcontrol,
1873                                  struct snd_ctl_elem_info *uinfo)
1874{
1875        u16 tuner_bands[HPI_TUNER_BAND_LAST];
1876        int num_bands = 0;
1877
1878        num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1879                                HPI_TUNER_BAND_LAST);
1880
1881        if (num_bands < 0)
1882                return num_bands;
1883
1884        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1885        uinfo->count = 1;
1886        uinfo->value.enumerated.items = num_bands;
1887
1888        if (num_bands > 0) {
1889                if (uinfo->value.enumerated.item >=
1890                                        uinfo->value.enumerated.items)
1891                        uinfo->value.enumerated.item =
1892                                uinfo->value.enumerated.items - 1;
1893
1894                strcpy(uinfo->value.enumerated.name,
1895                        asihpi_tuner_band_names[
1896                                tuner_bands[uinfo->value.enumerated.item]]);
1897
1898        }
1899        return 0;
1900}
1901
1902static int snd_asihpi_tuner_band_get(struct snd_kcontrol *kcontrol,
1903                                 struct snd_ctl_elem_value *ucontrol)
1904{
1905        u32 h_control = kcontrol->private_value;
1906        /*
1907        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1908        */
1909        u16 band, idx;
1910        u16 tuner_bands[HPI_TUNER_BAND_LAST];
1911        u32 num_bands = 0;
1912
1913        num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1914                                HPI_TUNER_BAND_LAST);
1915
1916        hpi_handle_error(hpi_tuner_get_band(ss, h_control, &band));
1917
1918        ucontrol->value.enumerated.item[0] = -1;
1919        for (idx = 0; idx < HPI_TUNER_BAND_LAST; idx++)
1920                if (tuner_bands[idx] == band) {
1921                        ucontrol->value.enumerated.item[0] = idx;
1922                        break;
1923                }
1924
1925        return 0;
1926}
1927
1928static int snd_asihpi_tuner_band_put(struct snd_kcontrol *kcontrol,
1929                                 struct snd_ctl_elem_value *ucontrol)
1930{
1931        /*
1932        struct snd_card_asihpi *asihpi = snd_kcontrol_chip(kcontrol);
1933        */
1934        u32 h_control = kcontrol->private_value;
1935        u16 band;
1936        u16 tuner_bands[HPI_TUNER_BAND_LAST];
1937        u32 num_bands = 0;
1938
1939        num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1940                        HPI_TUNER_BAND_LAST);
1941
1942        band = tuner_bands[ucontrol->value.enumerated.item[0]];
1943        hpi_handle_error(hpi_tuner_set_band(ss, h_control, band));
1944
1945        return 1;
1946}
1947
1948/* Freq */
1949
1950static int snd_asihpi_tuner_freq_info(struct snd_kcontrol *kcontrol,
1951                                  struct snd_ctl_elem_info *uinfo)
1952{
1953        u32 h_control = kcontrol->private_value;
1954        u16 err;
1955        u16 tuner_bands[HPI_TUNER_BAND_LAST];
1956        u16 num_bands = 0, band_iter, idx;
1957        u32 freq_range[3], temp_freq_range[3];
1958
1959        num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands,
1960                        HPI_TUNER_BAND_LAST);
1961
1962        freq_range[0] = INT_MAX;
1963        freq_range[1] = 0;
1964        freq_range[2] = INT_MAX;
1965
1966        for (band_iter = 0; band_iter < num_bands; band_iter++) {
1967                for (idx = 0; idx < 3; idx++) {
1968                        err = hpi_tuner_query_frequency(ss, h_control,
1969                                idx, tuner_bands[band_iter],
1970                                &temp_freq_range[idx]);
1971                        if (err != 0)
1972                                return err;
1973                }
1974
1975                /* skip band with bogus stepping */
1976                if (temp_freq_range[2] <= 0)
1977                        continue;
1978
1979                if (temp_freq_range[0] < freq_range[0])
1980                        freq_range[0] = temp_freq_range[0];
1981                if (temp_freq_range[1] > freq_range[1])
1982                        freq_range[1] = temp_freq_range[1];
1983                if (temp_freq_range[2] < freq_range[2])
1984                        freq_range[2] = temp_freq_range[2];
1985        }
1986
1987        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1988        uinfo->count = 1;
1989        uinfo->value.integer.min = ((int)freq_range[0]);
1990        uinfo->value.integer.max = ((int)freq_range[1]);
1991        uinfo->value.integer.step = ((int)freq_range[2]);
1992        return 0;
1993}
1994
1995static int snd_asihpi_tuner_freq_get(struct snd_kcontrol *kcontrol,
1996                                 struct snd_ctl_elem_value *ucontrol)
1997{
1998        u32 h_control = kcontrol->private_value;
1999        u32 freq;
2000
2001        hpi_handle_error(hpi_tuner_get_frequency(ss, h_control, &freq));
2002        ucontrol->value.integer.value[0] = freq;
2003
2004        return 0;
2005}
2006
2007static int snd_asihpi_tuner_freq_put(struct snd_kcontrol *kcontrol,
2008                                 struct snd_ctl_elem_value *ucontrol)
2009{
2010        u32 h_control = kcontrol->private_value;
2011        u32 freq;
2012
2013        freq = ucontrol->value.integer.value[0];
2014        hpi_handle_error(hpi_tuner_set_frequency(ss, h_control, freq));
2015
2016        return 1;
2017}
2018
2019/* Tuner control group initializer  */
2020static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi,
2021                                        struct hpi_control *hpi_ctl)
2022{
2023        struct snd_card *card = asihpi->card;
2024        struct snd_kcontrol_new snd_control;
2025
2026        snd_control.private_value = hpi_ctl->h_control;
2027        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2028
2029        if (!hpi_tuner_get_gain(ss, hpi_ctl->h_control, NULL)) {
2030                asihpi_ctl_init(&snd_control, hpi_ctl, "gain");
2031                snd_control.info = snd_asihpi_tuner_gain_info;
2032                snd_control.get = snd_asihpi_tuner_gain_get;
2033                snd_control.put = snd_asihpi_tuner_gain_put;
2034
2035                if (ctl_add(card, &snd_control, asihpi) < 0)
2036                        return -EINVAL;
2037        }
2038
2039        asihpi_ctl_init(&snd_control, hpi_ctl, "band");
2040        snd_control.info = snd_asihpi_tuner_band_info;
2041        snd_control.get = snd_asihpi_tuner_band_get;
2042        snd_control.put = snd_asihpi_tuner_band_put;
2043
2044        if (ctl_add(card, &snd_control, asihpi) < 0)
2045                return -EINVAL;
2046
2047        asihpi_ctl_init(&snd_control, hpi_ctl, "freq");
2048        snd_control.info = snd_asihpi_tuner_freq_info;
2049        snd_control.get = snd_asihpi_tuner_freq_get;
2050        snd_control.put = snd_asihpi_tuner_freq_put;
2051
2052        return ctl_add(card, &snd_control, asihpi);
2053}
2054
2055/*------------------------------------------------------------
2056   Meter controls
2057 ------------------------------------------------------------*/
2058static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol,
2059                                 struct snd_ctl_elem_info *uinfo)
2060{
2061        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2062        uinfo->count = HPI_MAX_CHANNELS;
2063        uinfo->value.integer.min = 0;
2064        uinfo->value.integer.max = 0x7FFFFFFF;
2065        return 0;
2066}
2067
2068/* linear values for 10dB steps */
2069static int log2lin[] = {
2070        0x7FFFFFFF, /* 0dB */
2071        679093956,
2072        214748365,
2073         67909396,
2074         21474837,
2075          6790940,
2076          2147484, /* -60dB */
2077           679094,
2078           214748, /* -80 */
2079            67909,
2080            21475, /* -100 */
2081             6791,
2082             2147,
2083              679,
2084              214,
2085               68,
2086               21,
2087                7,
2088                2
2089};
2090
2091static int snd_asihpi_meter_get(struct snd_kcontrol *kcontrol,
2092                                struct snd_ctl_elem_value *ucontrol)
2093{
2094        u32 h_control = kcontrol->private_value;
2095        short an_gain_mB[HPI_MAX_CHANNELS], i;
2096        u16 err;
2097
2098        err = hpi_meter_get_peak(ss, h_control, an_gain_mB);
2099
2100        for (i = 0; i < HPI_MAX_CHANNELS; i++) {
2101                if (err) {
2102                        ucontrol->value.integer.value[i] = 0;
2103                } else if (an_gain_mB[i] >= 0) {
2104                        ucontrol->value.integer.value[i] =
2105                                an_gain_mB[i] << 16;
2106                } else {
2107                        /* -ve is log value in millibels < -60dB,
2108                        * convert to (roughly!) linear,
2109                        */
2110                        ucontrol->value.integer.value[i] =
2111                                        log2lin[an_gain_mB[i] / -1000];
2112                }
2113        }
2114        return 0;
2115}
2116
2117static int __devinit snd_asihpi_meter_add(struct snd_card_asihpi *asihpi,
2118                                        struct hpi_control *hpi_ctl, int subidx)
2119{
2120        struct snd_card *card = asihpi->card;
2121        struct snd_kcontrol_new snd_control;
2122
2123        asihpi_ctl_init(&snd_control, hpi_ctl, "meter");
2124        snd_control.access =
2125            SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2126        snd_control.info = snd_asihpi_meter_info;
2127        snd_control.get = snd_asihpi_meter_get;
2128
2129        snd_control.index = subidx;
2130
2131        return ctl_add(card, &snd_control, asihpi);
2132}
2133
2134/*------------------------------------------------------------
2135   Multiplexer controls
2136 ------------------------------------------------------------*/
2137static int snd_card_asihpi_mux_count_sources(struct snd_kcontrol *snd_control)
2138{
2139        u32 h_control = snd_control->private_value;
2140        struct hpi_control hpi_ctl;
2141        int s, err;
2142        for (s = 0; s < 32; s++) {
2143                err = hpi_multiplexer_query_source(ss, h_control, s,
2144                                                  &hpi_ctl.
2145                                                  src_node_type,
2146                                                  &hpi_ctl.
2147                                                  src_node_index);
2148                if (err)
2149                        break;
2150        }
2151        return s;
2152}
2153
2154static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol,
2155                               struct snd_ctl_elem_info *uinfo)
2156{
2157        int err;
2158        u16 src_node_type, src_node_index;
2159        u32 h_control = kcontrol->private_value;
2160
2161        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2162        uinfo->count = 1;
2163        uinfo->value.enumerated.items =
2164            snd_card_asihpi_mux_count_sources(kcontrol);
2165
2166        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2167                uinfo->value.enumerated.item =
2168                    uinfo->value.enumerated.items - 1;
2169
2170        err =
2171            hpi_multiplexer_query_source(ss, h_control,
2172                                        uinfo->value.enumerated.item,
2173                                        &src_node_type, &src_node_index);
2174
2175        sprintf(uinfo->value.enumerated.name, "%s %d",
2176                asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE],
2177                src_node_index);
2178        return 0;
2179}
2180
2181static int snd_asihpi_mux_get(struct snd_kcontrol *kcontrol,
2182                              struct snd_ctl_elem_value *ucontrol)
2183{
2184        u32 h_control = kcontrol->private_value;
2185        u16 source_type, source_index;
2186        u16 src_node_type, src_node_index;
2187        int s;
2188
2189        hpi_handle_error(hpi_multiplexer_get_source(ss, h_control,
2190                                &source_type, &source_index));
2191        /* Should cache this search result! */
2192        for (s = 0; s < 256; s++) {
2193                if (hpi_multiplexer_query_source(ss, h_control, s,
2194                                            &src_node_type, &src_node_index))
2195                        break;
2196
2197                if ((source_type == src_node_type)
2198                    && (source_index == src_node_index)) {
2199                        ucontrol->value.enumerated.item[0] = s;
2200                        return 0;
2201                }
2202        }
2203        snd_printd(KERN_WARNING
2204                "control %x failed to match mux source %hu %hu\n",
2205                h_control, source_type, source_index);
2206        ucontrol->value.enumerated.item[0] = 0;
2207        return 0;
2208}
2209
2210static int snd_asihpi_mux_put(struct snd_kcontrol *kcontrol,
2211                              struct snd_ctl_elem_value *ucontrol)
2212{
2213        int change;
2214        u32 h_control = kcontrol->private_value;
2215        u16 source_type, source_index;
2216        u16 e;
2217
2218        change = 1;
2219
2220        e = hpi_multiplexer_query_source(ss, h_control,
2221                                    ucontrol->value.enumerated.item[0],
2222                                    &source_type, &source_index);
2223        if (!e)
2224                hpi_handle_error(
2225                        hpi_multiplexer_set_source(ss, h_control,
2226                                                source_type, source_index));
2227        return change;
2228}
2229
2230
2231static int  __devinit snd_asihpi_mux_add(struct snd_card_asihpi *asihpi,
2232                                        struct hpi_control *hpi_ctl)
2233{
2234        struct snd_card *card = asihpi->card;
2235        struct snd_kcontrol_new snd_control;
2236
2237#if ASI_STYLE_NAMES
2238        asihpi_ctl_init(&snd_control, hpi_ctl, "multiplexer");
2239#else
2240        asihpi_ctl_init(&snd_control, hpi_ctl, "route");
2241#endif
2242        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2243        snd_control.info = snd_asihpi_mux_info;
2244        snd_control.get = snd_asihpi_mux_get;
2245        snd_control.put = snd_asihpi_mux_put;
2246
2247        return ctl_add(card, &snd_control, asihpi);
2248
2249}
2250
2251/*------------------------------------------------------------
2252   Channel mode controls
2253 ------------------------------------------------------------*/
2254static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol,
2255                                 struct snd_ctl_elem_info *uinfo)
2256{
2257        static char *mode_names[HPI_CHANNEL_MODE_LAST] = {
2258                "normal", "swap",
2259                "from_left", "from_right",
2260                "to_left", "to_right"
2261        };
2262
2263        u32 h_control = kcontrol->private_value;
2264        u16 mode;
2265        int i;
2266
2267        /* HPI channel mode values can be from 1 to 6
2268        Some adapters only support a contiguous subset
2269        */
2270        for (i = 0; i < HPI_CHANNEL_MODE_LAST; i++)
2271                if (hpi_channel_mode_query_mode(
2272                        ss,  h_control, i, &mode))
2273                        break;
2274
2275        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2276        uinfo->count = 1;
2277        uinfo->value.enumerated.items = i;
2278
2279        if (uinfo->value.enumerated.item >= i)
2280                uinfo->value.enumerated.item = i - 1;
2281
2282        strcpy(uinfo->value.enumerated.name,
2283               mode_names[uinfo->value.enumerated.item]);
2284
2285        return 0;
2286}
2287
2288static int snd_asihpi_cmode_get(struct snd_kcontrol *kcontrol,
2289                                struct snd_ctl_elem_value *ucontrol)
2290{
2291        u32 h_control = kcontrol->private_value;
2292        u16 mode;
2293
2294        if (hpi_channel_mode_get(ss, h_control, &mode))
2295                mode = 1;
2296
2297        ucontrol->value.enumerated.item[0] = mode - 1;
2298
2299        return 0;
2300}
2301
2302static int snd_asihpi_cmode_put(struct snd_kcontrol *kcontrol,
2303                                struct snd_ctl_elem_value *ucontrol)
2304{
2305        int change;
2306        u32 h_control = kcontrol->private_value;
2307
2308        change = 1;
2309
2310        hpi_handle_error(hpi_channel_mode_set(ss, h_control,
2311                           ucontrol->value.enumerated.item[0] + 1));
2312        return change;
2313}
2314
2315
2316static int __devinit snd_asihpi_cmode_add(struct snd_card_asihpi *asihpi,
2317                                        struct hpi_control *hpi_ctl)
2318{
2319        struct snd_card *card = asihpi->card;
2320        struct snd_kcontrol_new snd_control;
2321
2322        asihpi_ctl_init(&snd_control, hpi_ctl, "channel mode");
2323        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
2324        snd_control.info = snd_asihpi_cmode_info;
2325        snd_control.get = snd_asihpi_cmode_get;
2326        snd_control.put = snd_asihpi_cmode_put;
2327
2328        return ctl_add(card, &snd_control, asihpi);
2329}
2330
2331/*------------------------------------------------------------
2332   Sampleclock source  controls
2333 ------------------------------------------------------------*/
2334
2335static char *sampleclock_sources[MAX_CLOCKSOURCES] =
2336    { "N/A", "local PLL", "AES/EBU sync", "word external", "word header",
2337          "SMPTE", "AES/EBU in1", "auto", "network", "invalid",
2338          "prev module",
2339          "AES/EBU in2", "AES/EBU in3", "AES/EBU in4", "AES/EBU in5",
2340          "AES/EBU in6", "AES/EBU in7", "AES/EBU in8"};
2341
2342
2343
2344static int snd_asihpi_clksrc_info(struct snd_kcontrol *kcontrol,
2345                                  struct snd_ctl_elem_info *uinfo)
2346{
2347        struct snd_card_asihpi *asihpi =
2348                        (struct snd_card_asihpi *)(kcontrol->private_data);
2349        struct clk_cache *clkcache = &asihpi->cc;
2350        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2351        uinfo->count = 1;
2352        uinfo->value.enumerated.items = clkcache->count;
2353
2354        if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2355                uinfo->value.enumerated.item =
2356                                uinfo->value.enumerated.items - 1;
2357
2358        strcpy(uinfo->value.enumerated.name,
2359               clkcache->s[uinfo->value.enumerated.item].name);
2360        return 0;
2361}
2362
2363static int snd_asihpi_clksrc_get(struct snd_kcontrol *kcontrol,
2364                                 struct snd_ctl_elem_value *ucontrol)
2365{
2366        struct snd_card_asihpi *asihpi =
2367                        (struct snd_card_asihpi *)(kcontrol->private_data);
2368        struct clk_cache *clkcache = &asihpi->cc;
2369        u32 h_control = kcontrol->private_value;
2370        u16 source, srcindex = 0;
2371        int i;
2372
2373        ucontrol->value.enumerated.item[0] = 0;
2374        if (hpi_sample_clock_get_source(ss, h_control, &source))
2375                source = 0;
2376
2377        if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2378                if (hpi_sample_clock_get_source_index(ss, h_control, &srcindex))
2379                        srcindex = 0;
2380
2381        for (i = 0; i < clkcache->count; i++)
2382                if ((clkcache->s[i].source == source) &&
2383                        (clkcache->s[i].index == srcindex))
2384                        break;
2385
2386        ucontrol->value.enumerated.item[0] = i;
2387
2388        return 0;
2389}
2390
2391static int snd_asihpi_clksrc_put(struct snd_kcontrol *kcontrol,
2392                                 struct snd_ctl_elem_value *ucontrol)
2393{
2394        struct snd_card_asihpi *asihpi =
2395                        (struct snd_card_asihpi *)(kcontrol->private_data);
2396        struct clk_cache *clkcache = &asihpi->cc;
2397        int change, item;
2398        u32 h_control = kcontrol->private_value;
2399
2400        change = 1;
2401        item = ucontrol->value.enumerated.item[0];
2402        if (item >= clkcache->count)
2403                item = clkcache->count-1;
2404
2405        hpi_handle_error(hpi_sample_clock_set_source(ss,
2406                                h_control, clkcache->s[item].source));
2407
2408        if (clkcache->s[item].source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2409                hpi_handle_error(hpi_sample_clock_set_source_index(ss,
2410                                h_control, clkcache->s[item].index));
2411        return change;
2412}
2413
2414/*------------------------------------------------------------
2415   Clkrate controls
2416 ------------------------------------------------------------*/
2417/* Need to change this to enumerated control with list of rates */
2418static int snd_asihpi_clklocal_info(struct snd_kcontrol *kcontrol,
2419                                   struct snd_ctl_elem_info *uinfo)
2420{
2421        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2422        uinfo->count = 1;
2423        uinfo->value.integer.min = 8000;
2424        uinfo->value.integer.max = 192000;
2425        uinfo->value.integer.step = 100;
2426
2427        return 0;
2428}
2429
2430static int snd_asihpi_clklocal_get(struct snd_kcontrol *kcontrol,
2431                                  struct snd_ctl_elem_value *ucontrol)
2432{
2433        u32 h_control = kcontrol->private_value;
2434        u32 rate;
2435        u16 e;
2436
2437        e = hpi_sample_clock_get_local_rate(ss, h_control, &rate);
2438        if (!e)
2439                ucontrol->value.integer.value[0] = rate;
2440        else
2441                ucontrol->value.integer.value[0] = 0;
2442        return 0;
2443}
2444
2445static int snd_asihpi_clklocal_put(struct snd_kcontrol *kcontrol,
2446                                  struct snd_ctl_elem_value *ucontrol)
2447{
2448        int change;
2449        u32 h_control = kcontrol->private_value;
2450
2451        /*  change = asihpi->mixer_clkrate[addr][0] != left ||
2452           asihpi->mixer_clkrate[addr][1] != right;
2453         */
2454        change = 1;
2455        hpi_handle_error(hpi_sample_clock_set_local_rate(ss, h_control,
2456                                      ucontrol->value.integer.value[0]));
2457        return change;
2458}
2459
2460static int snd_asihpi_clkrate_info(struct snd_kcontrol *kcontrol,
2461                                   struct snd_ctl_elem_info *uinfo)
2462{
2463        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2464        uinfo->count = 1;
2465        uinfo->value.integer.min = 8000;
2466        uinfo->value.integer.max = 192000;
2467        uinfo->value.integer.step = 100;
2468
2469        return 0;
2470}
2471
2472static int snd_asihpi_clkrate_get(struct snd_kcontrol *kcontrol,
2473                                  struct snd_ctl_elem_value *ucontrol)
2474{
2475        u32 h_control = kcontrol->private_value;
2476        u32 rate;
2477        u16 e;
2478
2479        e = hpi_sample_clock_get_sample_rate(ss, h_control, &rate);
2480        if (!e)
2481                ucontrol->value.integer.value[0] = rate;
2482        else
2483                ucontrol->value.integer.value[0] = 0;
2484        return 0;
2485}
2486
2487static int __devinit snd_asihpi_sampleclock_add(struct snd_card_asihpi *asihpi,
2488                                        struct hpi_control *hpi_ctl)
2489{
2490        struct snd_card *card = asihpi->card;
2491        struct snd_kcontrol_new snd_control;
2492
2493        struct clk_cache *clkcache = &asihpi->cc;
2494        u32 hSC =  hpi_ctl->h_control;
2495        int has_aes_in = 0;
2496        int i, j;
2497        u16 source;
2498
2499        snd_control.private_value = hpi_ctl->h_control;
2500
2501        clkcache->has_local = 0;
2502
2503        for (i = 0; i <= HPI_SAMPLECLOCK_SOURCE_LAST; i++) {
2504                if  (hpi_sample_clock_query_source(ss, hSC,
2505                                i, &source))
2506                        break;
2507                clkcache->s[i].source = source;
2508                clkcache->s[i].index = 0;
2509                clkcache->s[i].name = sampleclock_sources[source];
2510                if (source == HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT)
2511                        has_aes_in = 1;
2512                if (source == HPI_SAMPLECLOCK_SOURCE_LOCAL)
2513                        clkcache->has_local = 1;
2514        }
2515        if (has_aes_in)
2516                /* already will have picked up index 0 above */
2517                for (j = 1; j < 8; j++) {
2518                        if (hpi_sample_clock_query_source_index(ss, hSC,
2519                                j, HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT,
2520                                &source))
2521                                break;
2522                        clkcache->s[i].source =
2523                                HPI_SAMPLECLOCK_SOURCE_AESEBU_INPUT;
2524                        clkcache->s[i].index = j;
2525                        clkcache->s[i].name = sampleclock_sources[
2526                                        j+HPI_SAMPLECLOCK_SOURCE_LAST];
2527                        i++;
2528                }
2529        clkcache->count = i;
2530
2531        asihpi_ctl_init(&snd_control, hpi_ctl, "source");
2532        snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2533        snd_control.info = snd_asihpi_clksrc_info;
2534        snd_control.get = snd_asihpi_clksrc_get;
2535        snd_control.put = snd_asihpi_clksrc_put;
2536        if (ctl_add(card, &snd_control, asihpi) < 0)
2537                return -EINVAL;
2538
2539
2540        if (clkcache->has_local) {
2541                asihpi_ctl_init(&snd_control, hpi_ctl, "local_rate");
2542                snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE ;
2543                snd_control.info = snd_asihpi_clklocal_info;
2544                snd_control.get = snd_asihpi_clklocal_get;
2545                snd_control.put = snd_asihpi_clklocal_put;
2546
2547
2548                if (ctl_add(card, &snd_control, asihpi) < 0)
2549                        return -EINVAL;
2550        }
2551
2552        asihpi_ctl_init(&snd_control, hpi_ctl, "rate");
2553        snd_control.access =
2554            SNDRV_CTL_ELEM_ACCESS_VOLATILE | SNDRV_CTL_ELEM_ACCESS_READ;
2555        snd_control.info = snd_asihpi_clkrate_info;
2556        snd_control.get = snd_asihpi_clkrate_get;
2557
2558        return ctl_add(card, &snd_control, asihpi);
2559}
2560/*------------------------------------------------------------
2561   Mixer
2562 ------------------------------------------------------------*/
2563
2564static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi)
2565{
2566        struct snd_card *card = asihpi->card;
2567        unsigned int idx = 0;
2568        unsigned int subindex = 0;
2569        int err;
2570        struct hpi_control hpi_ctl, prev_ctl;
2571
2572        if (snd_BUG_ON(!asihpi))
2573                return -EINVAL;
2574        strcpy(card->mixername, "asihpi mixer");
2575
2576        err =
2577            hpi_mixer_open(ss, asihpi->adapter_index,
2578                          &asihpi->h_mixer);
2579        hpi_handle_error(err);
2580        if (err)
2581                return -err;
2582
2583        memset(&prev_ctl, 0, sizeof(prev_ctl));
2584        prev_ctl.control_type = -1;
2585
2586        for (idx = 0; idx < 2000; idx++) {
2587                err = hpi_mixer_get_control_by_index(
2588                                ss, asihpi->h_mixer,
2589                                idx,
2590                                &hpi_ctl.src_node_type,
2591                                &hpi_ctl.src_node_index,
2592                                &hpi_ctl.dst_node_type,
2593                                &hpi_ctl.dst_node_index,
2594                                &hpi_ctl.control_type,
2595                                &hpi_ctl.h_control);
2596                if (err) {
2597                        if (err == HPI_ERROR_CONTROL_DISABLED) {
2598                                if (mixer_dump)
2599                                        snd_printk(KERN_INFO
2600                                                   "disabled HPI control(%d)\n",
2601                                                   idx);
2602                                continue;
2603                        } else
2604                                break;
2605
2606                }
2607
2608                hpi_ctl.src_node_type -= HPI_SOURCENODE_NONE;
2609                hpi_ctl.dst_node_type -= HPI_DESTNODE_NONE;
2610
2611                /* ASI50xx in SSX mode has multiple meters on the same node.
2612                   Use subindex to create distinct ALSA controls
2613                   for any duplicated controls.
2614                */
2615                if ((hpi_ctl.control_type == prev_ctl.control_type) &&
2616                    (hpi_ctl.src_node_type == prev_ctl.src_node_type) &&
2617                    (hpi_ctl.src_node_index == prev_ctl.src_node_index) &&
2618                    (hpi_ctl.dst_node_type == prev_ctl.dst_node_type) &&
2619                    (hpi_ctl.dst_node_index == prev_ctl.dst_node_index))
2620                        subindex++;
2621                else
2622                        subindex = 0;
2623
2624                prev_ctl = hpi_ctl;
2625
2626                switch (hpi_ctl.control_type) {
2627                case HPI_CONTROL_VOLUME:
2628                        err = snd_asihpi_volume_add(asihpi, &hpi_ctl);
2629                        break;
2630                case HPI_CONTROL_LEVEL:
2631                        err = snd_asihpi_level_add(asihpi, &hpi_ctl);
2632                        break;
2633                case HPI_CONTROL_MULTIPLEXER:
2634                        err = snd_asihpi_mux_add(asihpi, &hpi_ctl);
2635                        break;
2636                case HPI_CONTROL_CHANNEL_MODE:
2637                        err = snd_asihpi_cmode_add(asihpi, &hpi_ctl);
2638                        break;
2639                case HPI_CONTROL_METER:
2640                        err = snd_asihpi_meter_add(asihpi, &hpi_ctl, subindex);
2641                        break;
2642                case HPI_CONTROL_SAMPLECLOCK:
2643                        err = snd_asihpi_sampleclock_add(
2644                                                asihpi, &hpi_ctl);
2645                        break;
2646                case HPI_CONTROL_CONNECTION:    /* ignore these */
2647                        continue;
2648                case HPI_CONTROL_TUNER:
2649                        err = snd_asihpi_tuner_add(asihpi, &hpi_ctl);
2650                        break;
2651                case HPI_CONTROL_AESEBU_TRANSMITTER:
2652                        err = snd_asihpi_aesebu_tx_add(asihpi, &hpi_ctl);
2653                        break;
2654                case HPI_CONTROL_AESEBU_RECEIVER:
2655                        err = snd_asihpi_aesebu_rx_add(asihpi, &hpi_ctl);
2656                        break;
2657                case HPI_CONTROL_VOX:
2658                case HPI_CONTROL_BITSTREAM:
2659                case HPI_CONTROL_MICROPHONE:
2660                case HPI_CONTROL_PARAMETRIC_EQ:
2661                case HPI_CONTROL_COMPANDER:
2662                default:
2663                        if (mixer_dump)
2664                                snd_printk(KERN_INFO
2665                                        "untranslated HPI control"
2666                                        "(%d) %d %d %d %d %d\n",
2667                                        idx,
2668                                        hpi_ctl.control_type,
2669                                        hpi_ctl.src_node_type,
2670                                        hpi_ctl.src_node_index,
2671                                        hpi_ctl.dst_node_type,
2672                                        hpi_ctl.dst_node_index);
2673                        continue;
2674                };
2675                if (err < 0)
2676                        return err;
2677        }
2678        if (HPI_ERROR_INVALID_OBJ_INDEX != err)
2679                hpi_handle_error(err);
2680
2681        snd_printk(KERN_INFO "%d mixer controls found\n", idx);
2682
2683        return 0;
2684}
2685
2686/*------------------------------------------------------------
2687   /proc interface
2688 ------------------------------------------------------------*/
2689
2690static void
2691snd_asihpi_proc_read(struct snd_info_entry *entry,
2692                        struct snd_info_buffer *buffer)
2693{
2694        struct snd_card_asihpi *asihpi = entry->private_data;
2695        u16 version;
2696        u32 h_control;
2697        u32 rate = 0;
2698        u16 source = 0;
2699        int err;
2700
2701        snd_iprintf(buffer, "ASIHPI driver proc file\n");
2702        snd_iprintf(buffer,
2703                "adapter ID=%4X\n_index=%d\n"
2704                "num_outstreams=%d\n_num_instreams=%d\n",
2705                asihpi->type, asihpi->adapter_index,
2706                asihpi->num_outstreams, asihpi->num_instreams);
2707
2708        version = asihpi->version;
2709        snd_iprintf(buffer,
2710                "serial#=%d\n_hw version %c%d\nDSP code version %03d\n",
2711                asihpi->serial_number, ((version >> 3) & 0xf) + 'A',
2712                version & 0x7,
2713                ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2714
2715        err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2716                                  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2717                                  HPI_CONTROL_SAMPLECLOCK, &h_control);
2718
2719        if (!err) {
2720                err = hpi_sample_clock_get_sample_rate(ss,
2721                                        h_control, &rate);
2722                err += hpi_sample_clock_get_source(ss, h_control, &source);
2723
2724                if (!err)
2725                        snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n",
2726                        rate, sampleclock_sources[source]);
2727        }
2728
2729}
2730
2731
2732static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi)
2733{
2734        struct snd_info_entry *entry;
2735
2736        if (!snd_card_proc_new(asihpi->card, "info", &entry))
2737                snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read);
2738}
2739
2740/*------------------------------------------------------------
2741   HWDEP
2742 ------------------------------------------------------------*/
2743
2744static int snd_asihpi_hpi_open(struct snd_hwdep *hw, struct file *file)
2745{
2746        if (enable_hpi_hwdep)
2747                return 0;
2748        else
2749                return -ENODEV;
2750
2751}
2752
2753static int snd_asihpi_hpi_release(struct snd_hwdep *hw, struct file *file)
2754{
2755        if (enable_hpi_hwdep)
2756                return asihpi_hpi_release(file);
2757        else
2758                return -ENODEV;
2759}
2760
2761static int snd_asihpi_hpi_ioctl(struct snd_hwdep *hw, struct file *file,
2762                                unsigned int cmd, unsigned long arg)
2763{
2764        if (enable_hpi_hwdep)
2765                return asihpi_hpi_ioctl(file, cmd, arg);
2766        else
2767                return -ENODEV;
2768}
2769
2770
2771/* results in /dev/snd/hwC#D0 file for each card with index #
2772   also /proc/asound/hwdep will contain '#-00: asihpi (HPI) for each card'
2773*/
2774static int __devinit snd_asihpi_hpi_new(struct snd_card_asihpi *asihpi,
2775        int device, struct snd_hwdep **rhwdep)
2776{
2777        struct snd_hwdep *hw;
2778        int err;
2779
2780        if (rhwdep)
2781                *rhwdep = NULL;
2782        err = snd_hwdep_new(asihpi->card, "HPI", device, &hw);
2783        if (err < 0)
2784                return err;
2785        strcpy(hw->name, "asihpi (HPI)");
2786        hw->iface = SNDRV_HWDEP_IFACE_LAST;
2787        hw->ops.open = snd_asihpi_hpi_open;
2788        hw->ops.ioctl = snd_asihpi_hpi_ioctl;
2789        hw->ops.release = snd_asihpi_hpi_release;
2790        hw->private_data = asihpi;
2791        if (rhwdep)
2792                *rhwdep = hw;
2793        return 0;
2794}
2795
2796/*------------------------------------------------------------
2797   CARD
2798 ------------------------------------------------------------*/
2799static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev,
2800                                       const struct pci_device_id *pci_id)
2801{
2802        int err;
2803
2804        u16 version;
2805        int pcm_substreams;
2806
2807        struct hpi_adapter *hpi_card;
2808        struct snd_card *card;
2809        struct snd_card_asihpi *asihpi;
2810
2811        u32 h_control;
2812        u32 h_stream;
2813
2814        static int dev;
2815        if (dev >= SNDRV_CARDS)
2816                return -ENODEV;
2817
2818        /* Should this be enable[hpi_card->index] ? */
2819        if (!enable[dev]) {
2820                dev++;
2821                return -ENOENT;
2822        }
2823
2824        err = asihpi_adapter_probe(pci_dev, pci_id);
2825        if (err < 0)
2826                return err;
2827
2828        hpi_card = pci_get_drvdata(pci_dev);
2829        /* first try to give the card the same index as its hardware index */
2830        err = snd_card_create(hpi_card->index,
2831                              id[hpi_card->index], THIS_MODULE,
2832                              sizeof(struct snd_card_asihpi),
2833                              &card);
2834        if (err < 0) {
2835                /* if that fails, try the default index==next available */
2836                err =
2837                    snd_card_create(index[dev], id[dev],
2838                                    THIS_MODULE,
2839                                    sizeof(struct snd_card_asihpi),
2840                                    &card);
2841                if (err < 0)
2842                        return err;
2843                snd_printk(KERN_WARNING
2844                        "**** WARNING **** adapter index %d->ALSA index %d\n",
2845                        hpi_card->index, card->number);
2846        }
2847
2848        asihpi = (struct snd_card_asihpi *) card->private_data;
2849        asihpi->card = card;
2850        asihpi->pci = hpi_card->pci;
2851        asihpi->adapter_index = hpi_card->index;
2852        hpi_handle_error(hpi_adapter_get_info(ss,
2853                                 asihpi->adapter_index,
2854                                 &asihpi->num_outstreams,
2855                                 &asihpi->num_instreams,
2856                                 &asihpi->version,
2857                                 &asihpi->serial_number, &asihpi->type));
2858
2859        version = asihpi->version;
2860        snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d "
2861                        "num_instreams=%d S/N=%d\n"
2862                        "hw version %c%d DSP code version %03d\n",
2863                        asihpi->type, asihpi->adapter_index,
2864                        asihpi->num_outstreams,
2865                        asihpi->num_instreams, asihpi->serial_number,
2866                        ((version >> 3) & 0xf) + 'A',
2867                        version & 0x7,
2868                        ((version >> 13) * 100) + ((version >> 7) & 0x3f));
2869
2870        pcm_substreams = asihpi->num_outstreams;
2871        if (pcm_substreams < asihpi->num_instreams)
2872                pcm_substreams = asihpi->num_instreams;
2873
2874        err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2875                HPI_ADAPTER_PROPERTY_CAPS1,
2876                NULL, &asihpi->support_grouping);
2877        if (err)
2878                asihpi->support_grouping = 0;
2879
2880        err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2881                HPI_ADAPTER_PROPERTY_CAPS2,
2882                &asihpi->support_mrx, NULL);
2883        if (err)
2884                asihpi->support_mrx = 0;
2885
2886        err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2887                HPI_ADAPTER_PROPERTY_INTERVAL,
2888                NULL, &asihpi->update_interval_frames);
2889        if (err)
2890                asihpi->update_interval_frames = 512;
2891
2892        hpi_handle_error(hpi_instream_open(ss, asihpi->adapter_index,
2893                             0, &h_stream));
2894
2895        err = hpi_instream_host_buffer_free(ss, h_stream);
2896        asihpi->support_mmap = (!err);
2897
2898        hpi_handle_error(hpi_instream_close(ss, h_stream));
2899
2900        err = hpi_adapter_get_property(ss, asihpi->adapter_index,
2901                HPI_ADAPTER_PROPERTY_CURCHANNELS,
2902                &asihpi->in_max_chans, &asihpi->out_max_chans);
2903        if (err) {
2904                asihpi->in_max_chans = 2;
2905                asihpi->out_max_chans = 2;
2906        }
2907
2908        snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n",
2909                        asihpi->support_mmap,
2910                        asihpi->support_grouping,
2911                        asihpi->support_mrx
2912              );
2913
2914
2915        err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams);
2916        if (err < 0) {
2917                snd_printk(KERN_ERR "pcm_new failed\n");
2918                goto __nodev;
2919        }
2920        err = snd_card_asihpi_mixer_new(asihpi);
2921        if (err < 0) {
2922                snd_printk(KERN_ERR "mixer_new failed\n");
2923                goto __nodev;
2924        }
2925
2926        err = hpi_mixer_get_control(ss, asihpi->h_mixer,
2927                                  HPI_SOURCENODE_CLOCK_SOURCE, 0, 0, 0,
2928                                  HPI_CONTROL_SAMPLECLOCK, &h_control);
2929
2930        if (!err)
2931                err = hpi_sample_clock_set_local_rate(
2932                        ss, h_control, adapter_fs);
2933
2934        snd_asihpi_proc_init(asihpi);
2935
2936        /* always create, can be enabled or disabled dynamically
2937            by enable_hwdep  module param*/
2938        snd_asihpi_hpi_new(asihpi, 0, NULL);
2939
2940        if (asihpi->support_mmap)
2941                strcpy(card->driver, "ASIHPI-MMAP");
2942        else
2943                strcpy(card->driver, "ASIHPI");
2944
2945        sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type);
2946        sprintf(card->longname, "%s %i",
2947                        card->shortname, asihpi->adapter_index);
2948        err = snd_card_register(card);
2949        if (!err) {
2950                hpi_card->snd_card_asihpi = card;
2951                dev++;
2952                return 0;
2953        }
2954__nodev:
2955        snd_card_free(card);
2956        snd_printk(KERN_ERR "snd_asihpi_probe error %d\n", err);
2957        return err;
2958
2959}
2960
2961static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev)
2962{
2963        struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev);
2964
2965        snd_card_free(hpi_card->snd_card_asihpi);
2966        hpi_card->snd_card_asihpi = NULL;
2967        asihpi_adapter_remove(pci_dev);
2968}
2969
2970static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
2971        {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_DSP6205,
2972                HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2973                (kernel_ulong_t)HPI_6205},
2974        {HPI_PCI_VENDOR_ID_TI, HPI_PCI_DEV_ID_PCI2040,
2975                HPI_PCI_VENDOR_ID_AUDIOSCIENCE, PCI_ANY_ID, 0, 0,
2976                (kernel_ulong_t)HPI_6000},
2977        {0,}
2978};
2979MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
2980
2981static struct pci_driver driver = {
2982        .name = "asihpi",
2983        .id_table = asihpi_pci_tbl,
2984        .probe = snd_asihpi_probe,
2985        .remove = __devexit_p(snd_asihpi_remove),
2986#ifdef CONFIG_PM
2987/*      .suspend = snd_asihpi_suspend,
2988        .resume = snd_asihpi_resume, */
2989#endif
2990};
2991
2992static int __init snd_asihpi_init(void)
2993{
2994        asihpi_init();
2995        return pci_register_driver(&driver);
2996}
2997
2998static void __exit snd_asihpi_exit(void)
2999{
3000
3001        pci_unregister_driver(&driver);
3002        asihpi_exit();
3003}
3004
3005module_init(snd_asihpi_init)
3006module_exit(snd_asihpi_exit)
3007
3008