19db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim/* 29db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * max9877.c -- amp driver for max9877 39db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * 49db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * Copyright (C) 2009 Samsung Electronics Co.Ltd 59db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * Author: Joonyoung Shim <jy0922.shim@samsung.com> 69db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * 79db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * This program is free software; you can redistribute it and/or modify it 89db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * under the terms of the GNU General Public License as published by the 99db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * Free Software Foundation; either version 2 of the License, or (at your 109db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * option) any later version. 119db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim * 129db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim */ 139db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 149db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include <linux/module.h> 159db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include <linux/init.h> 169db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include <linux/i2c.h> 179db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include <sound/soc.h> 189db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include <sound/tlv.h> 199db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 209db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim#include "max9877.h" 219db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 229db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic struct i2c_client *i2c; 239db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 249db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic u8 max9877_regs[5] = { 0x40, 0x00, 0x00, 0x00, 0x49 }; 259db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 269db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic void max9877_write_regs(void) 279db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 28a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim unsigned int i; 29a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim u8 data[6]; 30a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim 31a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim data[0] = MAX9877_INPUT_MODE; 32a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim for (i = 0; i < ARRAY_SIZE(max9877_regs); i++) 33a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim data[i + 1] = max9877_regs[i]; 34a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim 35a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim if (i2c_master_send(i2c, data, 6) != 6) 369db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim dev_err(&i2c->dev, "i2c write failed\n"); 379db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 389db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 399db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_get_reg(struct snd_kcontrol *kcontrol, 409db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 419db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 429db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct soc_mixer_control *mc = 439db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim (struct soc_mixer_control *)kcontrol->private_value; 44e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg = mc->reg; 45e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int shift = mc->shift; 46e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int mask = mc->max; 47e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int invert = mc->invert; 489db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 499db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask; 509db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 51e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim if (invert) 52e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim ucontrol->value.integer.value[0] = 53e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim mask - ucontrol->value.integer.value[0]; 549db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 559db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 569db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 579db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 589db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_set_reg(struct snd_kcontrol *kcontrol, 599db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 609db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 619db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct soc_mixer_control *mc = 629db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim (struct soc_mixer_control *)kcontrol->private_value; 63e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg = mc->reg; 64e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int shift = mc->shift; 65e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int mask = mc->max; 66e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int invert = mc->invert; 67e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int val = (ucontrol->value.integer.value[0] & mask); 68e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 69e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim if (invert) 70e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim val = mask - val; 71e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 72e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim if (((max9877_regs[reg] >> shift) & mask) == val) 73e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim return 0; 74e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 75e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_regs[reg] &= ~(mask << shift); 76e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_regs[reg] |= val << shift; 77e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_write_regs(); 78e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 79e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim return 1; 80e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim} 81e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 82e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shimstatic int max9877_get_2reg(struct snd_kcontrol *kcontrol, 83e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim struct snd_ctl_elem_value *ucontrol) 84e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim{ 85e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim struct soc_mixer_control *mc = 86e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim (struct soc_mixer_control *)kcontrol->private_value; 87e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg = mc->reg; 88e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg2 = mc->rreg; 89e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int shift = mc->shift; 90e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int mask = mc->max; 91e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 92e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask; 93e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask; 94e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 95e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim return 0; 96e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim} 97e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 98e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shimstatic int max9877_set_2reg(struct snd_kcontrol *kcontrol, 99e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim struct snd_ctl_elem_value *ucontrol) 100e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim{ 101e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim struct soc_mixer_control *mc = 102e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim (struct soc_mixer_control *)kcontrol->private_value; 103e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg = mc->reg; 104e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int reg2 = mc->rreg; 105e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int shift = mc->shift; 106e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int mask = mc->max; 107e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int val = (ucontrol->value.integer.value[0] & mask); 108e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int val2 = (ucontrol->value.integer.value[1] & mask); 109e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim unsigned int change = 1; 110e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim 111e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim if (((max9877_regs[reg] >> shift) & mask) == val) 1129db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim change = 0; 1139db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 114e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim if (((max9877_regs[reg2] >> shift) & mask) == val2) 115e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim change = 0; 1169db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1179db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim if (change) { 1189db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_regs[reg] &= ~(mask << shift); 119e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_regs[reg] |= val << shift; 1209db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_regs[reg2] &= ~(mask << shift); 121e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_regs[reg2] |= val2 << shift; 1229db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_write_regs(); 123e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim } 1249db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 125e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim return change; 1269db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 1279db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1289db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_get_out_mode(struct snd_kcontrol *kcontrol, 1299db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 1309db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 1319db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim u8 value = max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK; 1329db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1339db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim if (value) 1349db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim value -= 1; 1359db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1369db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim ucontrol->value.integer.value[0] = value; 1379db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 1389db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 1399db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1409db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_set_out_mode(struct snd_kcontrol *kcontrol, 1419db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 1429db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 1439db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim u8 value = ucontrol->value.integer.value[0]; 1449db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 145a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim value += 1; 1469db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1479db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK) == value) 1489db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 1499db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 150a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OUTMODE_MASK; 1519db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_regs[MAX9877_OUTPUT_MODE] |= value; 1529db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_write_regs(); 1539db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 1; 1549db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 1559db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1569db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_get_osc_mode(struct snd_kcontrol *kcontrol, 1579db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 1589db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 1599db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim u8 value = (max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK); 1609db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1619db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim value = value >> MAX9877_OSC_OFFSET; 1629db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1639db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim ucontrol->value.integer.value[0] = value; 1649db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 1659db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 1669db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1679db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int max9877_set_osc_mode(struct snd_kcontrol *kcontrol, 1689db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim struct snd_ctl_elem_value *ucontrol) 1699db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 1709db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim u8 value = ucontrol->value.integer.value[0]; 1719db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1729db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim value = value << MAX9877_OSC_OFFSET; 1739db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK) == value) 1749db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 1759db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 176a7569afa8b79ca9272b0d7544335bc05b5b721d6Joonyoung Shim max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OSC_MASK; 1779db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_regs[MAX9877_OUTPUT_MODE] |= value; 1789db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_write_regs(); 1799db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 1; 1809db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 1819db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1829db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const unsigned int max9877_pgain_tlv[] = { 1839db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim TLV_DB_RANGE_HEAD(2), 1849db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 0, 1, TLV_DB_SCALE_ITEM(0, 900, 0), 1859db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2, 2, TLV_DB_SCALE_ITEM(2000, 0, 0), 1869db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 1879db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1889db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const unsigned int max9877_output_tlv[] = { 1899db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim TLV_DB_RANGE_HEAD(4), 1909db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1), 1919db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0), 1929db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0), 1939db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0), 1949db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 1959db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 1969db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const char *max9877_out_mode[] = { 1979db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA -> SPK", 1989db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA -> HP", 1999db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA -> SPK and HP", 2009db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INB -> SPK", 2019db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INB -> HP", 2029db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INB -> SPK and HP", 2039db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA + INB -> SPK", 2049db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA + INB -> HP", 2059db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "INA + INB -> SPK and HP", 2069db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2079db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2089db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const char *max9877_osc_mode[] = { 2099db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "1176KHz", 2109db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "1100KHz", 2119db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim "700KHz", 2129db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2139db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2149db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const struct soc_enum max9877_enum[] = { 2159db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_out_mode), max9877_out_mode), 2169db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode), 2179db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2189db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2199db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const struct snd_kcontrol_new max9877_controls[] = { 2209db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT_TLV("MAX9877 PGAINA Playback Volume", 2219db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_INPUT_MODE, 0, 2, 0, 2229db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg, max9877_pgain_tlv), 2239db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT_TLV("MAX9877 PGAINB Playback Volume", 2249db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_INPUT_MODE, 2, 2, 0, 2259db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg, max9877_pgain_tlv), 2269db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT_TLV("MAX9877 Amp Speaker Playback Volume", 2279db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_SPK_VOLUME, 0, 31, 0, 2289db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg, max9877_output_tlv), 2299db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume", 2309db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0, 231e458a48f8776d624d05246471501c6086adb1d7aJoonyoung Shim max9877_get_2reg, max9877_set_2reg, max9877_output_tlv), 2329db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT("MAX9877 INB Stereo Switch", 2339db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_INPUT_MODE, 4, 1, 1, 2349db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg), 2359db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT("MAX9877 INA Stereo Switch", 2369db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_INPUT_MODE, 5, 1, 1, 2379db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg), 2389db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT("MAX9877 Zero-crossing detection Switch", 2399db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_INPUT_MODE, 6, 1, 0, 2409db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg), 2419db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT("MAX9877 Bypass Mode Switch", 2429db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_OUTPUT_MODE, 6, 1, 0, 2439db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg), 2449db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_SINGLE_EXT("MAX9877 Shutdown Mode Switch", 2459db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim MAX9877_OUTPUT_MODE, 7, 1, 1, 2469db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_reg, max9877_set_reg), 2479db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_ENUM_EXT("MAX9877 Output Mode", max9877_enum[0], 2489db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_out_mode, max9877_set_out_mode), 2499db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim SOC_ENUM_EXT("MAX9877 Oscillator Mode", max9877_enum[1], 2509db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_get_osc_mode, max9877_set_osc_mode), 2519db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2529db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2539db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim/* This function is called from ASoC machine driver */ 2549db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimint max9877_add_controls(struct snd_soc_codec *codec) 2559db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 2569db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return snd_soc_add_controls(codec, max9877_controls, 2579db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim ARRAY_SIZE(max9877_controls)); 2589db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 2599db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung ShimEXPORT_SYMBOL_GPL(max9877_add_controls); 2609db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2619db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int __devinit max9877_i2c_probe(struct i2c_client *client, 2629db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim const struct i2c_device_id *id) 2639db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 2649db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim i2c = client; 2659db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2669db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim max9877_write_regs(); 2679db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2689db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 2699db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 2709db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2719db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic __devexit int max9877_i2c_remove(struct i2c_client *client) 2729db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 2739db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim i2c = NULL; 2749db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2759db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return 0; 2769db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 2779db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2789db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic const struct i2c_device_id max9877_i2c_id[] = { 2799db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim { "max9877", 0 }, 2809db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim { } 2819db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2829db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung ShimMODULE_DEVICE_TABLE(i2c, max9877_i2c_id); 2839db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2849db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic struct i2c_driver max9877_i2c_driver = { 2859db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .driver = { 2869db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .name = "max9877", 2879db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .owner = THIS_MODULE, 2889db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim }, 2899db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .probe = max9877_i2c_probe, 2909db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .remove = __devexit_p(max9877_i2c_remove), 2919db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim .id_table = max9877_i2c_id, 2929db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim}; 2939db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 2949db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic int __init max9877_init(void) 2959db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 2969db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim return i2c_add_driver(&max9877_i2c_driver); 2979db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 2989db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimmodule_init(max9877_init); 2999db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 3009db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimstatic void __exit max9877_exit(void) 3019db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim{ 3029db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim i2c_del_driver(&max9877_i2c_driver); 3039db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim} 3049db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shimmodule_exit(max9877_exit); 3059db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung Shim 3069db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung ShimMODULE_DESCRIPTION("ASoC MAX9877 amp driver"); 3079db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung ShimMODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 3089db9ed977d4f1a317f5f4d467d43025fa27223d8Joonyoung ShimMODULE_LICENSE("GPL"); 309