cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

max9768.c (6321B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * MAX9768 AMP driver
      4 *
      5 * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K.
      6 */
      7
      8#include <linux/init.h>
      9#include <linux/module.h>
     10#include <linux/i2c.h>
     11#include <linux/slab.h>
     12#include <linux/gpio.h>
     13#include <linux/regmap.h>
     14
     15#include <sound/core.h>
     16#include <sound/soc.h>
     17#include <sound/tlv.h>
     18#include <sound/max9768.h>
     19
     20/* "Registers" */
     21#define MAX9768_VOL 0
     22#define MAX9768_CTRL 3
     23
     24/* Commands */
     25#define MAX9768_CTRL_PWM 0x15
     26#define MAX9768_CTRL_FILTERLESS 0x16
     27
     28struct max9768 {
     29	struct regmap *regmap;
     30	int mute_gpio;
     31	int shdn_gpio;
     32	u32 flags;
     33};
     34
     35static const struct reg_default max9768_default_regs[] = {
     36	{ 0, 0 },
     37	{ 3,  MAX9768_CTRL_FILTERLESS},
     38};
     39
     40static int max9768_get_gpio(struct snd_kcontrol *kcontrol,
     41	struct snd_ctl_elem_value *ucontrol)
     42{
     43	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
     44	struct max9768 *max9768 = snd_soc_component_get_drvdata(c);
     45	int val = gpio_get_value_cansleep(max9768->mute_gpio);
     46
     47	ucontrol->value.integer.value[0] = !val;
     48
     49	return 0;
     50}
     51
     52static int max9768_set_gpio(struct snd_kcontrol *kcontrol,
     53	struct snd_ctl_elem_value *ucontrol)
     54{
     55	struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
     56	struct max9768 *max9768 = snd_soc_component_get_drvdata(c);
     57
     58	gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]);
     59
     60	return 0;
     61}
     62
     63static const DECLARE_TLV_DB_RANGE(volume_tlv,
     64	0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0),
     65	1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0),
     66	2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0),
     67	3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0),
     68	4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0),
     69	5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0),
     70	6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0),
     71	7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0),
     72	8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0),
     73	9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0),
     74	10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0),
     75	11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0),
     76	12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0),
     77	13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0),
     78	14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0),
     79	15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0),
     80	18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0),
     81	19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0),
     82	20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0),
     83	21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0),
     84	22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0),
     85	23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0),
     86	24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0),
     87	25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0),
     88	26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0),
     89	27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0),
     90	28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0),
     91	31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0),
     92	32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0),
     93	35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0),
     94	38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0),
     95	40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0),
     96	41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0),
     97	42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0),
     98	43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0),
     99	44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0),
    100	45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0),
    101	46, 46, TLV_DB_SCALE_ITEM(50, 0, 0),
    102	47, 50, TLV_DB_SCALE_ITEM(120, 40, 0),
    103	51, 57, TLV_DB_SCALE_ITEM(290, 50, 0),
    104	58, 58, TLV_DB_SCALE_ITEM(650, 0, 0),
    105	59, 62, TLV_DB_SCALE_ITEM(700, 60, 0),
    106	63, 63, TLV_DB_SCALE_ITEM(950, 0, 0)
    107);
    108
    109static const struct snd_kcontrol_new max9768_volume[] = {
    110	SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv),
    111};
    112
    113static const struct snd_kcontrol_new max9768_mute[] = {
    114	SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio),
    115};
    116
    117static const struct snd_soc_dapm_widget max9768_dapm_widgets[] = {
    118SND_SOC_DAPM_INPUT("IN"),
    119
    120SND_SOC_DAPM_OUTPUT("OUT+"),
    121SND_SOC_DAPM_OUTPUT("OUT-"),
    122};
    123
    124static const struct snd_soc_dapm_route max9768_dapm_routes[] = {
    125	{ "OUT+", NULL, "IN" },
    126	{ "OUT-", NULL, "IN" },
    127};
    128
    129static int max9768_probe(struct snd_soc_component *component)
    130{
    131	struct max9768 *max9768 = snd_soc_component_get_drvdata(component);
    132	int ret;
    133
    134	if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) {
    135		ret = regmap_write(max9768->regmap, MAX9768_CTRL,
    136			MAX9768_CTRL_PWM);
    137		if (ret)
    138			return ret;
    139	}
    140
    141	if (gpio_is_valid(max9768->mute_gpio)) {
    142		ret = snd_soc_add_component_controls(component, max9768_mute,
    143				ARRAY_SIZE(max9768_mute));
    144		if (ret)
    145			return ret;
    146	}
    147
    148	return 0;
    149}
    150
    151static const struct snd_soc_component_driver max9768_component_driver = {
    152	.probe = max9768_probe,
    153	.controls = max9768_volume,
    154	.num_controls = ARRAY_SIZE(max9768_volume),
    155	.dapm_widgets = max9768_dapm_widgets,
    156	.num_dapm_widgets = ARRAY_SIZE(max9768_dapm_widgets),
    157	.dapm_routes = max9768_dapm_routes,
    158	.num_dapm_routes = ARRAY_SIZE(max9768_dapm_routes),
    159};
    160
    161static const struct regmap_config max9768_i2c_regmap_config = {
    162	.reg_bits = 2,
    163	.val_bits = 6,
    164	.max_register = 3,
    165	.reg_defaults = max9768_default_regs,
    166	.num_reg_defaults = ARRAY_SIZE(max9768_default_regs),
    167	.cache_type = REGCACHE_RBTREE,
    168};
    169
    170static int max9768_i2c_probe(struct i2c_client *client)
    171{
    172	struct max9768 *max9768;
    173	struct max9768_pdata *pdata = client->dev.platform_data;
    174	int err;
    175
    176	max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL);
    177	if (!max9768)
    178		return -ENOMEM;
    179
    180	if (pdata) {
    181		/* Mute on powerup to avoid clicks */
    182		err = devm_gpio_request_one(&client->dev, pdata->mute_gpio,
    183				GPIOF_INIT_HIGH, "MAX9768 Mute");
    184		max9768->mute_gpio = err ?: pdata->mute_gpio;
    185
    186		/* Activate chip by releasing shutdown, enables I2C */
    187		err = devm_gpio_request_one(&client->dev, pdata->shdn_gpio,
    188				GPIOF_INIT_HIGH, "MAX9768 Shutdown");
    189		max9768->shdn_gpio = err ?: pdata->shdn_gpio;
    190
    191		max9768->flags = pdata->flags;
    192	} else {
    193		max9768->shdn_gpio = -EINVAL;
    194		max9768->mute_gpio = -EINVAL;
    195	}
    196
    197	i2c_set_clientdata(client, max9768);
    198
    199	max9768->regmap = devm_regmap_init_i2c(client, &max9768_i2c_regmap_config);
    200	if (IS_ERR(max9768->regmap))
    201		return PTR_ERR(max9768->regmap);
    202
    203	return devm_snd_soc_register_component(&client->dev,
    204		&max9768_component_driver, NULL, 0);
    205}
    206
    207static const struct i2c_device_id max9768_i2c_id[] = {
    208	{ "max9768", 0 },
    209	{ }
    210};
    211MODULE_DEVICE_TABLE(i2c, max9768_i2c_id);
    212
    213static struct i2c_driver max9768_i2c_driver = {
    214	.driver = {
    215		.name = "max9768",
    216	},
    217	.probe_new = max9768_i2c_probe,
    218	.id_table = max9768_i2c_id,
    219};
    220module_i2c_driver(max9768_i2c_driver);
    221
    222MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>");
    223MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver");
    224MODULE_LICENSE("GPL v2");