linux/drivers/staging/intel_sst/intelmid_v1_control.c
<<
>>
Prefs
   1/*  intel_sst_v1_control.c - Intel SST Driver for audio engine
   2 *
   3 *  Copyright (C) 2008-10 Intel Corp
   4 *  Authors:    Vinod Koul <vinod.koul@intel.com>
   5 *      Harsha Priya <priya.harsha@intel.com>
   6 *      Dharageswari R <dharageswari.r@intel.com>
   7 *      KP Jeeja <jeeja.kp@intel.com>
   8 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   9 *
  10 *  This program is free software; you can redistribute it and/or modify
  11 *  it under the terms of the GNU General Public License as published by
  12 *  the Free Software Foundation; version 2 of the License.
  13 *
  14 *  This program is distributed in the hope that it will be useful, but
  15 *  WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 *  General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License along
  20 *  with this program; if not, write to the Free Software Foundation, Inc.,
  21 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  22 *
  23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  24 *
  25 *  This file contains the control operations of vendor 2
  26 */
  27
  28#include <linux/pci.h>
  29#include <linux/file.h>
  30#include <asm/mrst.h>
  31#include <sound/pcm.h>
  32#include "jack.h"
  33#include <sound/pcm_params.h>
  34#include <sound/control.h>
  35#include <sound/initval.h>
  36#include "intel_sst.h"
  37#include "intel_sst_ioctl.h"
  38#include "intelmid.h"
  39#include "intelmid_snd_control.h"
  40
  41#include <linux/gpio.h>
  42#define KOSKI_VOICE_CODEC_ENABLE 46
  43
  44enum _reg_v2 {
  45
  46        MASTER_CLOCK_PRESCALAR  = 0x205,
  47        SET_MASTER_AND_LR_CLK1  = 0x20b,
  48        SET_MASTER_AND_LR_CLK2  = 0x20c,
  49        MASTER_MODE_AND_DATA_DELAY = 0x20d,
  50        DIGITAL_INTERFACE_TO_DAI2 = 0x20e,
  51        CLK_AND_FS1 = 0x208,
  52        CLK_AND_FS2 = 0x209,
  53        DAI2_TO_DAC_HP = 0x210,
  54        HP_OP_SINGLE_ENDED = 0x224,
  55        ENABLE_OPDEV_CTRL = 0x226,
  56        ENABLE_DEV_AND_USE_XTAL = 0x227,
  57
  58        /* Max audio subsystem (PQ49) MAX 8921 */
  59        AS_IP_MODE_CTL = 0xF9,
  60        AS_LEFT_SPKR_VOL_CTL = 0xFA, /* Mono Earpiece volume control */
  61        AS_RIGHT_SPKR_VOL_CTL = 0xFB,
  62        AS_LEFT_HP_VOL_CTL = 0xFC,
  63        AS_RIGHT_HP_VOL_CTL = 0xFD,
  64        AS_OP_MIX_CTL = 0xFE,
  65        AS_CONFIG = 0xFF,
  66
  67        /* Headphone volume control & mute registers */
  68        VOL_CTRL_LT = 0x21c,
  69        VOL_CTRL_RT = 0x21d,
  70
  71};
  72/**
  73 * mx_init_card - initilize the sound card
  74 *
  75 * This initilizes the audio paths to know values in case of this sound card
  76 */
  77static int mx_init_card(void)
  78{
  79        struct sc_reg_access sc_access[] = {
  80                {0x200, 0x80, 0x00},
  81                {0x201, 0xC0, 0x00},
  82                {0x202, 0x00, 0x00},
  83                {0x203, 0x00, 0x00},
  84                {0x204, 0x02, 0x00},
  85                {0x205, 0x10, 0x00},
  86                {0x206, 0x60, 0x00},
  87                {0x207, 0x00, 0x00},
  88                {0x208, 0x90, 0x00},
  89                {0x209, 0x51, 0x00},
  90                {0x20a, 0x00, 0x00},
  91                {0x20b, 0x10, 0x00},
  92                {0x20c, 0x00, 0x00},
  93                {0x20d, 0x00, 0x00},
  94                {0x20e, 0x21, 0x00},
  95                {0x20f, 0x00, 0x00},
  96                {0x210, 0x84, 0x00},
  97                {0x211, 0xB3, 0x00},
  98                {0x212, 0x00, 0x00},
  99                {0x213, 0x00, 0x00},
 100                {0x214, 0x41, 0x00},
 101                {0x215, 0x00, 0x00},
 102                {0x216, 0x00, 0x00},
 103                {0x217, 0x00, 0x00},
 104                {0x218, 0x03, 0x00},
 105                {0x219, 0x03, 0x00},
 106                {0x21a, 0x00, 0x00},
 107                {0x21b, 0x00, 0x00},
 108                {0x21c, 0x00, 0x00},
 109                {0x21d, 0x00, 0x00},
 110                {0x21e, 0x00, 0x00},
 111                {0x21f, 0x00, 0x00},
 112                {0x220, 0x20, 0x00},
 113                {0x221, 0x20, 0x00},
 114                {0x222, 0x51, 0x00},
 115                {0x223, 0x20, 0x00},
 116                {0x224, 0x04, 0x00},
 117                {0x225, 0x80, 0x00},
 118                {0x226, 0x0F, 0x00},
 119                {0x227, 0x08, 0x00},
 120                {0xf9,  0x40, 0x00},
 121                {0xfa,  0x1f, 0x00},
 122                {0xfb,  0x1f, 0x00},
 123                {0xfc,  0x1f, 0x00},
 124                {0xfd,  0x1f, 0x00},
 125                {0xfe,  0x00, 0x00},
 126                {0xff,  0x0c, 0x00},
 127        };
 128        snd_pmic_ops_mx.card_status = SND_CARD_INIT_DONE;
 129        snd_pmic_ops_mx.num_channel = 2;
 130        snd_pmic_ops_mx.master_mute = UNMUTE;
 131        snd_pmic_ops_mx.mute_status = UNMUTE;
 132        return sst_sc_reg_access(sc_access, PMIC_WRITE, 47);
 133}
 134
 135static int mx_init_capture_card(void)
 136{
 137        struct sc_reg_access sc_access[] = {
 138                {0x206, 0x5a, 0x0},
 139                {0x207, 0xbe, 0x0},
 140                {0x208, 0x90, 0x0},
 141                {0x209, 0x32, 0x0},
 142                {0x20e, 0x22, 0x0},
 143                {0x210, 0x84, 0x0},
 144                {0x223, 0x20, 0x0},
 145                {0x226, 0xC0, 0x0},
 146        };
 147
 148        int retval = 0;
 149
 150        retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 8);
 151        if (0 != retval) {
 152                /* pmic communication fails */
 153                pr_debug("sst: pmic commn failed\n");
 154                return retval;
 155        }
 156
 157        pr_debug("sst: Capture configuration complete!!\n");
 158        return 0;
 159}
 160
 161static int mx_init_playback_card(void)
 162{
 163        struct sc_reg_access sc_access[] = {
 164                {0x206, 0x00, 0x0},
 165                {0x207, 0x00, 0x0},
 166                {0x208, 0x00, 0x0},
 167                {0x209, 0x51, 0x0},
 168                {0x20e, 0x51, 0x0},
 169                {0x210, 0x21, 0x0},
 170                {0x223, 0x01, 0x0},
 171        };
 172        int retval = 0;
 173
 174        retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 9);
 175        if (0 != retval) {
 176                /* pmic communication fails */
 177                pr_debug("sst: pmic commn failed\n");
 178                return retval;
 179        }
 180
 181        pr_debug("sst: Playback configuration complete!!\n");
 182        return 0;
 183}
 184
 185static int mx_enable_audiodac(int value)
 186{
 187        struct sc_reg_access sc_access[3];
 188        int mute_val = 0;
 189        int mute_val1 = 0;
 190        int retval = 0;
 191
 192        sc_access[0].reg_addr = AS_LEFT_HP_VOL_CTL;
 193        sc_access[1].reg_addr = AS_RIGHT_HP_VOL_CTL;
 194
 195        if (value == UNMUTE) {
 196                mute_val = 0x1F;
 197                mute_val1 = 0x00;
 198        } else {
 199                mute_val = 0x00;
 200                mute_val1 = 0x40;
 201        }
 202        sc_access[0].mask = sc_access[1].mask = MASK0|MASK1|MASK2|MASK3|MASK4;
 203        sc_access[0].value = sc_access[1].value = (u8)mute_val;
 204        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 205        if (retval)
 206                return retval;
 207        pr_debug("sst: mute status = %d", snd_pmic_ops_mx.mute_status);
 208        if (snd_pmic_ops_mx.mute_status == MUTE ||
 209                                snd_pmic_ops_mx.master_mute == MUTE)
 210                return retval;
 211
 212        sc_access[0].reg_addr = VOL_CTRL_LT;
 213        sc_access[1].reg_addr = VOL_CTRL_RT;
 214        sc_access[0].mask = sc_access[1].mask = MASK6;
 215        sc_access[0].value = sc_access[1].value = mute_val1;
 216        if (snd_pmic_ops_mx.num_channel == 1)
 217                sc_access[1].value = 0x40;
 218        return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 219}
 220
 221static int mx_power_up_pb(unsigned int port)
 222{
 223
 224        int retval = 0;
 225        struct sc_reg_access sc_access[3];
 226
 227        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 228                retval = mx_init_card();
 229                if (retval)
 230                        return retval;
 231        }
 232        retval = mx_enable_audiodac(MUTE);
 233        if (retval)
 234                return retval;
 235
 236        msleep(10);
 237
 238        sc_access[0].reg_addr = AS_CONFIG;
 239        sc_access[0].mask  = MASK7;
 240        sc_access[0].value = 0x80;
 241        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 242        if (retval)
 243                return retval;
 244
 245        sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
 246        sc_access[0].mask  = 0xff;
 247        sc_access[0].value = 0x3C;
 248        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 249        if (retval)
 250                return retval;
 251
 252        sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
 253        sc_access[0].mask  = 0x80;
 254        sc_access[0].value = 0x80;
 255        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 256        if (retval)
 257                return retval;
 258
 259        return mx_enable_audiodac(UNMUTE);
 260}
 261
 262static int mx_power_down_pb(void)
 263{
 264        struct sc_reg_access sc_access[3];
 265        int retval = 0;
 266
 267        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 268                retval = mx_init_card();
 269                if (retval)
 270                        return retval;
 271        }
 272
 273        retval = mx_enable_audiodac(MUTE);
 274        if (retval)
 275                return retval;
 276
 277        sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
 278        sc_access[0].mask  = MASK3|MASK2;
 279        sc_access[0].value = 0x00;
 280
 281        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 282        if (retval)
 283                return retval;
 284
 285        return mx_enable_audiodac(UNMUTE);
 286}
 287
 288static int mx_power_up_cp(unsigned int port)
 289{
 290        int retval = 0;
 291        struct sc_reg_access sc_access[] = {
 292                {ENABLE_DEV_AND_USE_XTAL, 0x80, MASK7},
 293                {ENABLE_OPDEV_CTRL, 0x3, 0x3},
 294        };
 295
 296        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 297                retval = mx_init_card();
 298                if (retval)
 299                        return retval;
 300        }
 301
 302        return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 303}
 304
 305static int mx_power_down_cp(void)
 306{
 307        struct sc_reg_access sc_access[] = {
 308                {ENABLE_OPDEV_CTRL, 0x00, MASK1|MASK0},
 309        };
 310        int retval = 0;
 311
 312        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 313                retval = mx_init_card();
 314                if (retval)
 315                        return retval;
 316        }
 317
 318        return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 319}
 320
 321static int mx_power_down(void)
 322{
 323        int retval = 0;
 324        struct sc_reg_access sc_access[3];
 325
 326        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 327                retval = mx_init_card();
 328                if (retval)
 329                        return retval;
 330        }
 331
 332        retval = mx_enable_audiodac(MUTE);
 333        if (retval)
 334                return retval;
 335
 336        sc_access[0].reg_addr = AS_CONFIG;
 337        sc_access[0].mask  = MASK7;
 338        sc_access[0].value = 0x00;
 339        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 340        if (retval)
 341                return retval;
 342
 343        sc_access[0].reg_addr = ENABLE_DEV_AND_USE_XTAL;
 344        sc_access[0].mask  = MASK7;
 345        sc_access[0].value = 0x00;
 346        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 347        if (retval)
 348                return retval;
 349
 350        sc_access[0].reg_addr = ENABLE_OPDEV_CTRL;
 351        sc_access[0].mask  = MASK3|MASK2;
 352        sc_access[0].value = 0x00;
 353        retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1);
 354        if (retval)
 355                return retval;
 356
 357        return mx_enable_audiodac(UNMUTE);
 358}
 359
 360static int mx_set_pcm_voice_params(void)
 361{
 362        int retval = 0;
 363        struct sc_reg_access sc_access[] = {
 364                {0x200, 0x80, 0x00},
 365                {0x201, 0xC0, 0x00},
 366                {0x202, 0x00, 0x00},
 367                {0x203, 0x00, 0x00},
 368                {0x204, 0x0e, 0x00},
 369                {0x205, 0x20, 0x00},
 370                {0x206, 0x8f, 0x00},
 371                {0x207, 0x21, 0x00},
 372                {0x208, 0x18, 0x00},
 373                {0x209, 0x32, 0x00},
 374                {0x20a, 0x00, 0x00},
 375                {0x20b, 0x5A, 0x00},
 376                {0x20c, 0xBE, 0x00},/* 0x00 -> 0xBE Koski */
 377                {0x20d, 0x00, 0x00}, /* DAI2 'off' */
 378                {0x20e, 0x40, 0x00},
 379                {0x20f, 0x00, 0x00},
 380                {0x210, 0x84, 0x00},
 381                {0x211, 0x33, 0x00}, /* Voice filter */
 382                {0x212, 0x00, 0x00},
 383                {0x213, 0x00, 0x00},
 384                {0x214, 0x41, 0x00},
 385                {0x215, 0x00, 0x00},
 386                {0x216, 0x00, 0x00},
 387                {0x217, 0x20, 0x00},
 388                {0x218, 0x00, 0x00},
 389                {0x219, 0x00, 0x00},
 390                {0x21a, 0x40, 0x00},
 391                {0x21b, 0x40, 0x00},
 392                {0x21c, 0x09, 0x00},
 393                {0x21d, 0x09, 0x00},
 394                {0x21e, 0x00, 0x00},
 395                {0x21f, 0x00, 0x00},
 396                {0x220, 0x00, 0x00}, /* Microphone configurations */
 397                {0x221, 0x00, 0x00}, /* Microphone configurations */
 398                {0x222, 0x50, 0x00}, /* Microphone configurations */
 399                {0x223, 0x21, 0x00}, /* Microphone configurations */
 400                {0x224, 0x00, 0x00},
 401                {0x225, 0x80, 0x00},
 402                {0xf9, 0x40, 0x00},
 403                {0xfa, 0x19, 0x00},
 404                {0xfb, 0x19, 0x00},
 405                {0xfc, 0x12, 0x00},
 406                {0xfd, 0x12, 0x00},
 407                {0xfe, 0x00, 0x00},
 408        };
 409
 410        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 411                retval = mx_init_card();
 412                if (retval)
 413                        return retval;
 414        }
 415        pr_debug("sst: SST DBG mx_set_pcm_voice_params called\n");
 416        return sst_sc_reg_access(sc_access, PMIC_WRITE, 44);
 417}
 418
 419static int mx_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
 420{
 421        int retval = 0;
 422
 423        int config1 = 0, config2 = 0, filter = 0xB3;
 424        struct sc_reg_access sc_access[5];
 425
 426        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 427                retval = mx_init_card();
 428                if (retval)
 429                        return retval;
 430        }
 431
 432        switch (sfreq) {
 433        case 8000:
 434                config1 = 0x10;
 435                config2 = 0x00;
 436                filter = 0x33;
 437                break;
 438        case 11025:
 439                config1 = 0x16;
 440                config2 = 0x0d;
 441                break;
 442        case 12000:
 443                config1 = 0x18;
 444                config2 = 0x00;
 445                break;
 446        case 16000:
 447                config1 = 0x20;
 448                config2 = 0x00;
 449                break;
 450        case 22050:
 451                config1 = 0x2c;
 452                config2 = 0x1a;
 453                break;
 454        case 24000:
 455                config1 = 0x30;
 456                config2 = 0x00;
 457                break;
 458        case 32000:
 459                config1 = 0x40;
 460                config2 = 0x00;
 461                break;
 462        case 44100:
 463                config1 = 0x58;
 464                config2 = 0x33;
 465                break;
 466        case 48000:
 467                config1 = 0x60;
 468                config2 = 0x00;
 469                break;
 470        }
 471        snd_pmic_ops_mx.num_channel = num_channel;
 472        /*mute the right channel if MONO*/
 473        if (snd_pmic_ops_mx.num_channel == 1)   {
 474                sc_access[0].reg_addr = VOL_CTRL_RT;
 475                sc_access[0].value = 0x40;
 476                sc_access[0].mask = MASK6;
 477
 478                sc_access[1].reg_addr = 0x224;
 479                sc_access[1].value = 0x05;
 480                sc_access[1].mask = MASK0|MASK1|MASK2;
 481
 482                retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 483                if (retval)
 484                        return retval;
 485        } else {
 486                sc_access[0].reg_addr = VOL_CTRL_RT;
 487                sc_access[0].value = 0x00;
 488                sc_access[0].mask = MASK6;
 489
 490                sc_access[1].reg_addr = 0x224;
 491                sc_access[1].value = 0x04;
 492                sc_access[1].mask = MASK0|MASK1|MASK2;
 493
 494                retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 495                if (retval)
 496                        return retval;
 497        }
 498        sc_access[0].reg_addr = 0x206;
 499        sc_access[0].value = config1;
 500        sc_access[1].reg_addr = 0x207;
 501        sc_access[1].value = config2;
 502
 503        if (word_size == 16) {
 504                sc_access[2].value = 0x51;
 505                sc_access[3].value = 0x31;
 506        } else if (word_size == 24) {
 507                sc_access[2].value = 0x52;
 508                sc_access[3].value = 0x92;
 509        }
 510
 511        sc_access[2].reg_addr = 0x209;
 512        sc_access[3].reg_addr = 0x20e;
 513
 514        sc_access[4].reg_addr = 0x211;
 515        sc_access[4].value = filter;
 516
 517        return sst_sc_reg_access(sc_access, PMIC_WRITE, 5);
 518}
 519
 520static int mx_set_selected_output_dev(u8 dev_id)
 521{
 522        struct sc_reg_access sc_access[2];
 523        int num_reg = 0;
 524        int retval = 0;
 525
 526        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 527                retval = mx_init_card();
 528                if (retval)
 529                        return retval;
 530        }
 531
 532        pr_debug("sst: mx_set_selected_output_dev dev_id:0x%x\n", dev_id);
 533        snd_pmic_ops_mx.output_dev_id = dev_id;
 534        switch (dev_id) {
 535        case STEREO_HEADPHONE:
 536                sc_access[0].reg_addr = 0xFF;
 537                sc_access[0].value = 0x8C;
 538                sc_access[0].mask =
 539                        MASK2|MASK3|MASK5|MASK6|MASK4;
 540
 541                num_reg = 1;
 542                break;
 543        case MONO_EARPIECE:
 544        case INTERNAL_SPKR:
 545                sc_access[0].reg_addr = 0xFF;
 546                sc_access[0].value = 0xb0;
 547                sc_access[0].mask =  MASK2|MASK3|MASK5|MASK6|MASK4;
 548
 549                num_reg = 1;
 550                break;
 551        case RECEIVER:
 552                pr_debug("sst: RECEIVER Koski selected\n");
 553
 554                /* configuration - AS enable, receiver enable */
 555                sc_access[0].reg_addr = 0xFF;
 556                sc_access[0].value = 0x81;
 557                sc_access[0].mask = 0xff;
 558
 559                num_reg = 1;
 560                break;
 561        default:
 562                pr_err("sst: Not a valid output dev\n");
 563                return 0;
 564        }
 565        return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
 566}
 567
 568
 569static int mx_set_voice_port(int status)
 570{
 571        int retval = 0;
 572
 573        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 574                retval = mx_init_card();
 575                if (retval)
 576                        return retval;
 577        }
 578        if (status == ACTIVATE)
 579                retval = mx_set_pcm_voice_params();
 580
 581        return retval;
 582}
 583
 584static int mx_set_audio_port(int status)
 585{
 586        return 0;
 587}
 588
 589static int mx_set_selected_input_dev(u8 dev_id)
 590{
 591        struct sc_reg_access sc_access[2];
 592        int num_reg = 0;
 593        int retval = 0;
 594
 595        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 596                retval = mx_init_card();
 597                if (retval)
 598                        return retval;
 599        }
 600        snd_pmic_ops_mx.input_dev_id = dev_id;
 601        pr_debug("sst: mx_set_selected_input_dev dev_id:0x%x\n", dev_id);
 602
 603        switch (dev_id) {
 604        case AMIC:
 605                sc_access[0].reg_addr = 0x223;
 606                sc_access[0].value = 0x00;
 607                sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
 608                sc_access[1].reg_addr = 0x222;
 609                sc_access[1].value = 0x50;
 610                sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
 611                num_reg = 2;
 612                break;
 613
 614        case HS_MIC:
 615                sc_access[0].reg_addr = 0x223;
 616                sc_access[0].value = 0x20;
 617                sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
 618                sc_access[1].reg_addr = 0x222;
 619                sc_access[1].value = 0x51;
 620                sc_access[1].mask = MASK7|MASK6|MASK5|MASK4;
 621                num_reg = 2;
 622                break;
 623        case DMIC:
 624                sc_access[1].reg_addr = 0x222;
 625                sc_access[1].value = 0x00;
 626                sc_access[1].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
 627                sc_access[0].reg_addr = 0x223;
 628                sc_access[0].value = 0x20;
 629                sc_access[0].mask = MASK7|MASK6|MASK5|MASK4|MASK0;
 630                num_reg = 2;
 631                break;
 632        }
 633        return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg);
 634}
 635
 636static int mx_set_mute(int dev_id, u8 value)
 637{
 638        struct sc_reg_access sc_access[5];
 639        int num_reg = 0;
 640        int retval = 0;
 641
 642        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 643                retval = mx_init_card();
 644                if (retval)
 645                        return retval;
 646        }
 647
 648
 649        pr_debug("sst: set_mute dev_id:0x%x , value:%d\n", dev_id, value);
 650
 651        switch (dev_id) {
 652        case PMIC_SND_DMIC_MUTE:
 653        case PMIC_SND_AMIC_MUTE:
 654        case PMIC_SND_HP_MIC_MUTE:
 655                sc_access[0].reg_addr = 0x220;
 656                sc_access[1].reg_addr = 0x221;
 657                sc_access[2].reg_addr = 0x223;
 658                if (value == MUTE) {
 659                        sc_access[0].value = 0x00;
 660                        sc_access[1].value = 0x00;
 661                        if (snd_pmic_ops_mx.input_dev_id == DMIC)
 662                                sc_access[2].value = 0x00;
 663                        else
 664                                sc_access[2].value = 0x20;
 665                } else {
 666                        sc_access[0].value = 0x20;
 667                        sc_access[1].value = 0x20;
 668                        if (snd_pmic_ops_mx.input_dev_id == DMIC)
 669                                sc_access[2].value = 0x20;
 670                        else
 671                                sc_access[2].value = 0x00;
 672                }
 673                sc_access[0].mask = MASK5|MASK6;
 674                sc_access[1].mask = MASK5|MASK6;
 675                sc_access[2].mask = MASK5|MASK6;
 676                num_reg = 3;
 677                break;
 678        case PMIC_SND_LEFT_SPEAKER_MUTE:
 679        case PMIC_SND_LEFT_HP_MUTE:
 680                sc_access[0].reg_addr = VOL_CTRL_LT;
 681                if (value == MUTE)
 682                        sc_access[0].value = 0x40;
 683                else
 684                        sc_access[0].value = 0x00;
 685                sc_access[0].mask = MASK6;
 686                num_reg = 1;
 687                snd_pmic_ops_mx.mute_status = value;
 688                break;
 689        case PMIC_SND_RIGHT_SPEAKER_MUTE:
 690        case PMIC_SND_RIGHT_HP_MUTE:
 691                sc_access[0].reg_addr = VOL_CTRL_RT;
 692                if (snd_pmic_ops_mx.num_channel == 1)
 693                        value = MUTE;
 694                if (value == MUTE)
 695                        sc_access[0].value = 0x40;
 696                else
 697                        sc_access[0].value = 0x00;
 698                sc_access[0].mask = MASK6;
 699                num_reg = 1;
 700                snd_pmic_ops_mx.mute_status = value;
 701                break;
 702        case PMIC_SND_MUTE_ALL:
 703                sc_access[0].reg_addr = VOL_CTRL_RT;
 704                sc_access[1].reg_addr = VOL_CTRL_LT;
 705                sc_access[2].reg_addr = 0x220;
 706                sc_access[3].reg_addr = 0x221;
 707                sc_access[4].reg_addr = 0x223;
 708                snd_pmic_ops_mx.master_mute = value;
 709                if (value == MUTE) {
 710                        sc_access[0].value = sc_access[1].value = 0x40;
 711                        sc_access[2].value = 0x00;
 712                        sc_access[3].value = 0x00;
 713                        if (snd_pmic_ops_mx.input_dev_id == DMIC)
 714                                sc_access[4].value = 0x00;
 715                        else
 716                                sc_access[4].value = 0x20;
 717
 718                } else {
 719                        sc_access[0].value = sc_access[1].value = 0x00;
 720                        sc_access[2].value = sc_access[3].value = 0x20;
 721                                sc_access[4].value = 0x20;
 722                        if (snd_pmic_ops_mx.input_dev_id == DMIC)
 723                                sc_access[4].value = 0x20;
 724                        else
 725                                sc_access[4].value = 0x00;
 726
 727
 728                }
 729                if (snd_pmic_ops_mx.num_channel == 1)
 730                        sc_access[0].value = 0x40;
 731                sc_access[0].mask = sc_access[1].mask = MASK6;
 732                sc_access[2].mask = MASK5|MASK6;
 733                sc_access[3].mask = MASK5|MASK6|MASK2|MASK4;
 734                sc_access[4].mask = MASK5|MASK6|MASK4;
 735
 736                num_reg = 5;
 737                break;
 738        case PMIC_SND_RECEIVER_MUTE:
 739                sc_access[0].reg_addr =  VOL_CTRL_RT;
 740                if (value == MUTE)
 741                        sc_access[0].value = 0x40;
 742                else
 743                        sc_access[0].value = 0x00;
 744                sc_access[0].mask = MASK6;
 745                num_reg = 1;
 746                break;
 747        }
 748
 749        return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
 750}
 751
 752static int mx_set_vol(int dev_id, int value)
 753{
 754        struct sc_reg_access sc_access[2] = {{0},};
 755        int num_reg = 0;
 756        int retval = 0;
 757
 758        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 759                retval = mx_init_card();
 760                if (retval)
 761                        return retval;
 762        }
 763        pr_debug("sst: set_vol dev_id:0x%x ,value:%d\n", dev_id, value);
 764        switch (dev_id) {
 765        case PMIC_SND_RECEIVER_VOL:
 766                return 0;
 767                break;
 768        case PMIC_SND_CAPTURE_VOL:
 769                sc_access[0].reg_addr = 0x220;
 770                sc_access[1].reg_addr = 0x221;
 771                sc_access[0].value = sc_access[1].value = -value;
 772                sc_access[0].mask = sc_access[1].mask =
 773                        (MASK0|MASK1|MASK2|MASK3|MASK4);
 774                num_reg = 2;
 775                break;
 776        case PMIC_SND_LEFT_PB_VOL:
 777                sc_access[0].value = -value;
 778                sc_access[0].reg_addr = VOL_CTRL_LT;
 779                sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
 780                num_reg = 1;
 781                break;
 782        case PMIC_SND_RIGHT_PB_VOL:
 783                sc_access[0].value = -value;
 784                sc_access[0].reg_addr = VOL_CTRL_RT;
 785                sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
 786                if (snd_pmic_ops_mx.num_channel == 1) {
 787                        sc_access[0].value = 0x40;
 788                        sc_access[0].mask = MASK6;
 789                        sc_access[0].reg_addr = VOL_CTRL_RT;
 790                }
 791                num_reg = 1;
 792                break;
 793        }
 794        return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, num_reg);
 795}
 796
 797static int mx_get_mute(int dev_id, u8 *value)
 798{
 799        struct sc_reg_access sc_access[4] = {{0},};
 800        int retval = 0, num_reg = 0, mask = 0;
 801
 802        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 803                retval = mx_init_card();
 804                if (retval)
 805                        return retval;
 806        }
 807        switch (dev_id) {
 808        case PMIC_SND_DMIC_MUTE:
 809        case PMIC_SND_AMIC_MUTE:
 810        case PMIC_SND_HP_MIC_MUTE:
 811                sc_access[0].reg_addr = 0x220;
 812                mask = MASK5|MASK6;
 813                num_reg = 1;
 814                retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
 815                if (retval)
 816                        return retval;
 817                *value = sc_access[0].value & mask;
 818                if (*value)
 819                        *value = UNMUTE;
 820                else
 821                        *value = MUTE;
 822                return retval;
 823        case PMIC_SND_LEFT_HP_MUTE:
 824        case PMIC_SND_LEFT_SPEAKER_MUTE:
 825                sc_access[0].reg_addr = VOL_CTRL_LT;
 826                num_reg = 1;
 827                mask = MASK6;
 828                break;
 829        case PMIC_SND_RIGHT_HP_MUTE:
 830        case PMIC_SND_RIGHT_SPEAKER_MUTE:
 831                sc_access[0].reg_addr = VOL_CTRL_RT;
 832                num_reg = 1;
 833                mask = MASK6;
 834                break;
 835        }
 836        retval = sst_sc_reg_access(sc_access, PMIC_READ, num_reg);
 837        if (retval)
 838                return retval;
 839        *value = sc_access[0].value & mask;
 840        if (*value)
 841                *value = MUTE;
 842        else
 843                *value = UNMUTE;
 844        return retval;
 845}
 846
 847static int mx_get_vol(int dev_id, int *value)
 848{
 849        struct sc_reg_access sc_access = {0,};
 850        int retval = 0, mask = 0, num_reg = 0;
 851
 852        if (snd_pmic_ops_mx.card_status == SND_CARD_UN_INIT) {
 853                retval = mx_init_card();
 854                if (retval)
 855                        return retval;
 856        }
 857        switch (dev_id) {
 858        case PMIC_SND_CAPTURE_VOL:
 859                sc_access.reg_addr = 0x220;
 860                mask = MASK0|MASK1|MASK2|MASK3|MASK4;
 861                num_reg = 1;
 862                break;
 863        case PMIC_SND_LEFT_PB_VOL:
 864                sc_access.reg_addr = VOL_CTRL_LT;
 865                mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
 866                num_reg = 1;
 867                break;
 868        case PMIC_SND_RIGHT_PB_VOL:
 869                sc_access.reg_addr = VOL_CTRL_RT;
 870                mask = MASK0|MASK1|MASK2|MASK3|MASK4|MASK5;
 871                num_reg = 1;
 872                break;
 873        }
 874        retval = sst_sc_reg_access(&sc_access, PMIC_READ, num_reg);
 875        if (retval)
 876                return retval;
 877        *value = -(sc_access.value & mask);
 878        pr_debug("sst: get volume value extracted %d\n", *value);
 879        return retval;
 880}
 881
 882struct snd_pmic_ops snd_pmic_ops_mx = {
 883        .set_input_dev = mx_set_selected_input_dev,
 884        .set_output_dev = mx_set_selected_output_dev,
 885        .set_mute = mx_set_mute,
 886        .get_mute = mx_get_mute,
 887        .set_vol = mx_set_vol,
 888        .get_vol = mx_get_vol,
 889        .init_card = mx_init_card,
 890        .set_pcm_audio_params = mx_set_pcm_audio_params,
 891        .set_pcm_voice_params = mx_set_pcm_voice_params,
 892        .set_voice_port = mx_set_voice_port,
 893        .set_audio_port = mx_set_audio_port,
 894        .power_up_pmic_pb = mx_power_up_pb,
 895        .power_up_pmic_cp = mx_power_up_cp,
 896        .power_down_pmic_pb = mx_power_down_pb,
 897        .power_down_pmic_cp = mx_power_down_cp,
 898        .power_down_pmic =  mx_power_down,
 899};
 900
 901
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.