Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.18 154 lines 4.0 kB view raw
1/* 2 * LM4857 AMP driver 3 * 4 * Copyright 2007 Wolfson Microelectronics PLC. 5 * Author: Graeme Gregory 6 * graeme.gregory@wolfsonmicro.com 7 * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. 13 * 14 */ 15 16#include <linux/init.h> 17#include <linux/module.h> 18#include <linux/i2c.h> 19#include <linux/regmap.h> 20#include <linux/slab.h> 21 22#include <sound/core.h> 23#include <sound/soc.h> 24#include <sound/tlv.h> 25 26static const struct reg_default lm4857_default_regs[] = { 27 { 0x0, 0x00 }, 28 { 0x1, 0x00 }, 29 { 0x2, 0x00 }, 30 { 0x3, 0x00 }, 31}; 32 33/* The register offsets in the cache array */ 34#define LM4857_MVOL 0 35#define LM4857_LVOL 1 36#define LM4857_RVOL 2 37#define LM4857_CTRL 3 38 39/* the shifts required to set these bits */ 40#define LM4857_3D 5 41#define LM4857_WAKEUP 5 42#define LM4857_EPGAIN 4 43 44static const unsigned int lm4857_mode_values[] = { 45 0, 46 6, 47 7, 48 8, 49 9, 50}; 51 52static const char * const lm4857_mode_texts[] = { 53 "Off", 54 "Earpiece", 55 "Loudspeaker", 56 "Loudspeaker + Headphone", 57 "Headphone", 58}; 59 60static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(lm4857_mode_enum, 61 LM4857_CTRL, 0, 0xf, lm4857_mode_texts, lm4857_mode_values); 62 63static const struct snd_kcontrol_new lm4857_mode_ctrl = 64 SOC_DAPM_ENUM("Mode", lm4857_mode_enum); 65 66static const struct snd_soc_dapm_widget lm4857_dapm_widgets[] = { 67 SND_SOC_DAPM_INPUT("IN"), 68 69 SND_SOC_DAPM_DEMUX("Mode", SND_SOC_NOPM, 0, 0, &lm4857_mode_ctrl), 70 71 SND_SOC_DAPM_OUTPUT("LS"), 72 SND_SOC_DAPM_OUTPUT("HP"), 73 SND_SOC_DAPM_OUTPUT("EP"), 74}; 75 76static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); 77static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); 78 79static const struct snd_kcontrol_new lm4857_controls[] = { 80 SOC_SINGLE_TLV("Left Playback Volume", LM4857_LVOL, 0, 31, 0, 81 stereo_tlv), 82 SOC_SINGLE_TLV("Right Playback Volume", LM4857_RVOL, 0, 31, 0, 83 stereo_tlv), 84 SOC_SINGLE_TLV("Mono Playback Volume", LM4857_MVOL, 0, 31, 0, 85 mono_tlv), 86 SOC_SINGLE("Spk 3D Playback Switch", LM4857_LVOL, LM4857_3D, 1, 0), 87 SOC_SINGLE("HP 3D Playback Switch", LM4857_RVOL, LM4857_3D, 1, 0), 88 SOC_SINGLE("Fast Wakeup Playback Switch", LM4857_CTRL, 89 LM4857_WAKEUP, 1, 0), 90 SOC_SINGLE("Earpiece 6dB Playback Switch", LM4857_CTRL, 91 LM4857_EPGAIN, 1, 0), 92}; 93 94static const struct snd_soc_dapm_route lm4857_routes[] = { 95 { "Mode", NULL, "IN" }, 96 { "LS", "Loudspeaker", "Mode" }, 97 { "LS", "Loudspeaker + Headphone", "Mode" }, 98 { "HP", "Headphone", "Mode" }, 99 { "HP", "Loudspeaker + Headphone", "Mode" }, 100 { "EP", "Earpiece", "Mode" }, 101}; 102 103static const struct snd_soc_component_driver lm4857_component_driver = { 104 .controls = lm4857_controls, 105 .num_controls = ARRAY_SIZE(lm4857_controls), 106 .dapm_widgets = lm4857_dapm_widgets, 107 .num_dapm_widgets = ARRAY_SIZE(lm4857_dapm_widgets), 108 .dapm_routes = lm4857_routes, 109 .num_dapm_routes = ARRAY_SIZE(lm4857_routes), 110}; 111 112static const struct regmap_config lm4857_regmap_config = { 113 .val_bits = 6, 114 .reg_bits = 2, 115 116 .max_register = LM4857_CTRL, 117 118 .cache_type = REGCACHE_FLAT, 119 .reg_defaults = lm4857_default_regs, 120 .num_reg_defaults = ARRAY_SIZE(lm4857_default_regs), 121}; 122 123static int lm4857_i2c_probe(struct i2c_client *i2c, 124 const struct i2c_device_id *id) 125{ 126 struct regmap *regmap; 127 128 regmap = devm_regmap_init_i2c(i2c, &lm4857_regmap_config); 129 if (IS_ERR(regmap)) 130 return PTR_ERR(regmap); 131 132 return devm_snd_soc_register_component(&i2c->dev, 133 &lm4857_component_driver, NULL, 0); 134} 135 136static const struct i2c_device_id lm4857_i2c_id[] = { 137 { "lm4857", 0 }, 138 { } 139}; 140MODULE_DEVICE_TABLE(i2c, lm4857_i2c_id); 141 142static struct i2c_driver lm4857_i2c_driver = { 143 .driver = { 144 .name = "lm4857", 145 }, 146 .probe = lm4857_i2c_probe, 147 .id_table = lm4857_i2c_id, 148}; 149 150module_i2c_driver(lm4857_i2c_driver); 151 152MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 153MODULE_DESCRIPTION("LM4857 amplifier driver"); 154MODULE_LICENSE("GPL");