1b7482f52SPhilipp Zabel /* 2b7482f52SPhilipp Zabel * uda1380.c - Philips UDA1380 ALSA SoC audio driver 3b7482f52SPhilipp Zabel * 4b7482f52SPhilipp Zabel * This program is free software; you can redistribute it and/or modify 5b7482f52SPhilipp Zabel * it under the terms of the GNU General Public License version 2 as 6b7482f52SPhilipp Zabel * published by the Free Software Foundation. 7b7482f52SPhilipp Zabel * 8b7482f52SPhilipp Zabel * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com> 9b7482f52SPhilipp Zabel * Improved support for DAPM and audio routing/mixing capabilities, 10b7482f52SPhilipp Zabel * added TLV support. 11b7482f52SPhilipp Zabel * 12b7482f52SPhilipp Zabel * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC 13b7482f52SPhilipp Zabel * codec model. 14b7482f52SPhilipp Zabel * 15b7482f52SPhilipp Zabel * Copyright (c) 2005 Giorgio Padrin <giorgio@mandarinlogiq.org> 16b7482f52SPhilipp Zabel * Copyright 2005 Openedhand Ltd. 17b7482f52SPhilipp Zabel */ 18b7482f52SPhilipp Zabel 19b7482f52SPhilipp Zabel #include <linux/module.h> 20b7482f52SPhilipp Zabel #include <linux/init.h> 21b7482f52SPhilipp Zabel #include <linux/types.h> 22b7482f52SPhilipp Zabel #include <linux/string.h> 23b7482f52SPhilipp Zabel #include <linux/slab.h> 24b7482f52SPhilipp Zabel #include <linux/errno.h> 25b7482f52SPhilipp Zabel #include <linux/ioctl.h> 26b7482f52SPhilipp Zabel #include <linux/delay.h> 27b7482f52SPhilipp Zabel #include <linux/i2c.h> 28b7482f52SPhilipp Zabel #include <sound/core.h> 29b7482f52SPhilipp Zabel #include <sound/control.h> 30b7482f52SPhilipp Zabel #include <sound/initval.h> 31b7482f52SPhilipp Zabel #include <sound/info.h> 32b7482f52SPhilipp Zabel #include <sound/soc.h> 33b7482f52SPhilipp Zabel #include <sound/soc-dapm.h> 34b7482f52SPhilipp Zabel #include <sound/tlv.h> 35b7482f52SPhilipp Zabel 36b7482f52SPhilipp Zabel #include "uda1380.h" 37b7482f52SPhilipp Zabel 38b7482f52SPhilipp Zabel #define UDA1380_VERSION "0.6" 39b7482f52SPhilipp Zabel 40b7482f52SPhilipp Zabel /* 41b7482f52SPhilipp Zabel * uda1380 register cache 42b7482f52SPhilipp Zabel */ 43b7482f52SPhilipp Zabel static const u16 uda1380_reg[UDA1380_CACHEREGNUM] = { 44b7482f52SPhilipp Zabel 0x0502, 0x0000, 0x0000, 0x3f3f, 45b7482f52SPhilipp Zabel 0x0202, 0x0000, 0x0000, 0x0000, 46b7482f52SPhilipp Zabel 0x0000, 0x0000, 0x0000, 0x0000, 47b7482f52SPhilipp Zabel 0x0000, 0x0000, 0x0000, 0x0000, 48b7482f52SPhilipp Zabel 0x0000, 0xff00, 0x0000, 0x4800, 49b7482f52SPhilipp Zabel 0x0000, 0x0000, 0x0000, 0x0000, 50b7482f52SPhilipp Zabel 0x0000, 0x0000, 0x0000, 0x0000, 51b7482f52SPhilipp Zabel 0x0000, 0x0000, 0x0000, 0x0000, 52b7482f52SPhilipp Zabel 0x0000, 0x8000, 0x0002, 0x0000, 53b7482f52SPhilipp Zabel }; 54b7482f52SPhilipp Zabel 55b7482f52SPhilipp Zabel /* 56b7482f52SPhilipp Zabel * read uda1380 register cache 57b7482f52SPhilipp Zabel */ 58b7482f52SPhilipp Zabel static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, 59b7482f52SPhilipp Zabel unsigned int reg) 60b7482f52SPhilipp Zabel { 61b7482f52SPhilipp Zabel u16 *cache = codec->reg_cache; 62b7482f52SPhilipp Zabel if (reg == UDA1380_RESET) 63b7482f52SPhilipp Zabel return 0; 64b7482f52SPhilipp Zabel if (reg >= UDA1380_CACHEREGNUM) 65b7482f52SPhilipp Zabel return -1; 66b7482f52SPhilipp Zabel return cache[reg]; 67b7482f52SPhilipp Zabel } 68b7482f52SPhilipp Zabel 69b7482f52SPhilipp Zabel /* 70b7482f52SPhilipp Zabel * write uda1380 register cache 71b7482f52SPhilipp Zabel */ 72b7482f52SPhilipp Zabel static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, 73b7482f52SPhilipp Zabel u16 reg, unsigned int value) 74b7482f52SPhilipp Zabel { 75b7482f52SPhilipp Zabel u16 *cache = codec->reg_cache; 76b7482f52SPhilipp Zabel if (reg >= UDA1380_CACHEREGNUM) 77b7482f52SPhilipp Zabel return; 78b7482f52SPhilipp Zabel cache[reg] = value; 79b7482f52SPhilipp Zabel } 80b7482f52SPhilipp Zabel 81b7482f52SPhilipp Zabel /* 82b7482f52SPhilipp Zabel * write to the UDA1380 register space 83b7482f52SPhilipp Zabel */ 84b7482f52SPhilipp Zabel static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, 85b7482f52SPhilipp Zabel unsigned int value) 86b7482f52SPhilipp Zabel { 87b7482f52SPhilipp Zabel u8 data[3]; 88b7482f52SPhilipp Zabel 89b7482f52SPhilipp Zabel /* data is 90b7482f52SPhilipp Zabel * data[0] is register offset 91b7482f52SPhilipp Zabel * data[1] is MS byte 92b7482f52SPhilipp Zabel * data[2] is LS byte 93b7482f52SPhilipp Zabel */ 94b7482f52SPhilipp Zabel data[0] = reg; 95b7482f52SPhilipp Zabel data[1] = (value & 0xff00) >> 8; 96b7482f52SPhilipp Zabel data[2] = value & 0x00ff; 97b7482f52SPhilipp Zabel 98b7482f52SPhilipp Zabel uda1380_write_reg_cache(codec, reg, value); 99b7482f52SPhilipp Zabel 100b7482f52SPhilipp Zabel /* the interpolator & decimator regs must only be written when the 101b7482f52SPhilipp Zabel * codec DAI is active. 102b7482f52SPhilipp Zabel */ 103b7482f52SPhilipp Zabel if (!codec->active && (reg >= UDA1380_MVOL)) 104b7482f52SPhilipp Zabel return 0; 105b7482f52SPhilipp Zabel pr_debug("uda1380: hw write %x val %x\n", reg, value); 106b7482f52SPhilipp Zabel if (codec->hw_write(codec->control_data, data, 3) == 3) { 107b7482f52SPhilipp Zabel unsigned int val; 108b7482f52SPhilipp Zabel i2c_master_send(codec->control_data, data, 1); 109b7482f52SPhilipp Zabel i2c_master_recv(codec->control_data, data, 2); 110b7482f52SPhilipp Zabel val = (data[0]<<8) | data[1]; 111b7482f52SPhilipp Zabel if (val != value) { 112b7482f52SPhilipp Zabel pr_debug("uda1380: READ BACK VAL %x\n", 113b7482f52SPhilipp Zabel (data[0]<<8) | data[1]); 114b7482f52SPhilipp Zabel return -EIO; 115b7482f52SPhilipp Zabel } 116b7482f52SPhilipp Zabel return 0; 117b7482f52SPhilipp Zabel } else 118b7482f52SPhilipp Zabel return -EIO; 119b7482f52SPhilipp Zabel } 120b7482f52SPhilipp Zabel 121b7482f52SPhilipp Zabel #define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) 122b7482f52SPhilipp Zabel 123b7482f52SPhilipp Zabel /* declarations of ALSA reg_elem_REAL controls */ 124b7482f52SPhilipp Zabel static const char *uda1380_deemp[] = { 125b7482f52SPhilipp Zabel "None", 126b7482f52SPhilipp Zabel "32kHz", 127b7482f52SPhilipp Zabel "44.1kHz", 128b7482f52SPhilipp Zabel "48kHz", 129b7482f52SPhilipp Zabel "96kHz", 130b7482f52SPhilipp Zabel }; 131b7482f52SPhilipp Zabel static const char *uda1380_input_sel[] = { 132b7482f52SPhilipp Zabel "Line", 133b7482f52SPhilipp Zabel "Mic + Line R", 134b7482f52SPhilipp Zabel "Line L", 135b7482f52SPhilipp Zabel "Mic", 136b7482f52SPhilipp Zabel }; 137b7482f52SPhilipp Zabel static const char *uda1380_output_sel[] = { 138b7482f52SPhilipp Zabel "DAC", 139b7482f52SPhilipp Zabel "Analog Mixer", 140b7482f52SPhilipp Zabel }; 141b7482f52SPhilipp Zabel static const char *uda1380_spf_mode[] = { 142b7482f52SPhilipp Zabel "Flat", 143b7482f52SPhilipp Zabel "Minimum1", 144b7482f52SPhilipp Zabel "Minimum2", 145b7482f52SPhilipp Zabel "Maximum" 146b7482f52SPhilipp Zabel }; 147b7482f52SPhilipp Zabel static const char *uda1380_capture_sel[] = { 148b7482f52SPhilipp Zabel "ADC", 149b7482f52SPhilipp Zabel "Digital Mixer" 150b7482f52SPhilipp Zabel }; 151b7482f52SPhilipp Zabel static const char *uda1380_sel_ns[] = { 152b7482f52SPhilipp Zabel "3rd-order", 153b7482f52SPhilipp Zabel "5th-order" 154b7482f52SPhilipp Zabel }; 155b7482f52SPhilipp Zabel static const char *uda1380_mix_control[] = { 156b7482f52SPhilipp Zabel "off", 157b7482f52SPhilipp Zabel "PCM only", 158b7482f52SPhilipp Zabel "before sound processing", 159b7482f52SPhilipp Zabel "after sound processing" 160b7482f52SPhilipp Zabel }; 161b7482f52SPhilipp Zabel static const char *uda1380_sdet_setting[] = { 162b7482f52SPhilipp Zabel "3200", 163b7482f52SPhilipp Zabel "4800", 164b7482f52SPhilipp Zabel "9600", 165b7482f52SPhilipp Zabel "19200" 166b7482f52SPhilipp Zabel }; 167b7482f52SPhilipp Zabel static const char *uda1380_os_setting[] = { 168b7482f52SPhilipp Zabel "single-speed", 169b7482f52SPhilipp Zabel "double-speed (no mixing)", 170b7482f52SPhilipp Zabel "quad-speed (no mixing)" 171b7482f52SPhilipp Zabel }; 172b7482f52SPhilipp Zabel 173b7482f52SPhilipp Zabel static const struct soc_enum uda1380_deemp_enum[] = { 174b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_DEEMP, 8, 5, uda1380_deemp), 175b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_DEEMP, 0, 5, uda1380_deemp), 176b7482f52SPhilipp Zabel }; 177b7482f52SPhilipp Zabel static const struct soc_enum uda1380_input_sel_enum = 178b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_ADC, 2, 4, uda1380_input_sel); /* SEL_MIC, SEL_LNA */ 179b7482f52SPhilipp Zabel static const struct soc_enum uda1380_output_sel_enum = 180b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_PM, 7, 2, uda1380_output_sel); /* R02_EN_AVC */ 181b7482f52SPhilipp Zabel static const struct soc_enum uda1380_spf_enum = 182b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_MODE, 14, 4, uda1380_spf_mode); /* M */ 183b7482f52SPhilipp Zabel static const struct soc_enum uda1380_capture_sel_enum = 184b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_IFACE, 6, 2, uda1380_capture_sel); /* SEL_SOURCE */ 185b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sel_ns_enum = 186b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_MIXER, 14, 2, uda1380_sel_ns); /* SEL_NS */ 187b7482f52SPhilipp Zabel static const struct soc_enum uda1380_mix_enum = 188b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_MIXER, 12, 4, uda1380_mix_control); /* MIX, MIX_POS */ 189b7482f52SPhilipp Zabel static const struct soc_enum uda1380_sdet_enum = 190b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_MIXER, 4, 4, uda1380_sdet_setting); /* SD_VALUE */ 191b7482f52SPhilipp Zabel static const struct soc_enum uda1380_os_enum = 192b7482f52SPhilipp Zabel SOC_ENUM_SINGLE(UDA1380_MIXER, 0, 3, uda1380_os_setting); /* OS */ 193b7482f52SPhilipp Zabel 194b7482f52SPhilipp Zabel /* 195b7482f52SPhilipp Zabel * from -48 dB in 1.5 dB steps (mute instead of -49.5 dB) 196b7482f52SPhilipp Zabel */ 197b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(amix_tlv, -4950, 150, 1); 198b7482f52SPhilipp Zabel 199b7482f52SPhilipp Zabel /* 200b7482f52SPhilipp Zabel * from -78 dB in 1 dB steps (3 dB steps, really. LSB are ignored), 201b7482f52SPhilipp Zabel * from -66 dB in 0.5 dB steps (2 dB steps, really) and 202b7482f52SPhilipp Zabel * from -52 dB in 0.25 dB steps 203b7482f52SPhilipp Zabel */ 204b7482f52SPhilipp Zabel static const unsigned int mvol_tlv[] = { 205b7482f52SPhilipp Zabel TLV_DB_RANGE_HEAD(3), 206b7482f52SPhilipp Zabel 0, 15, TLV_DB_SCALE_ITEM(-8200, 100, 1), 207b7482f52SPhilipp Zabel 16, 43, TLV_DB_SCALE_ITEM(-6600, 50, 0), 208b7482f52SPhilipp Zabel 44, 252, TLV_DB_SCALE_ITEM(-5200, 25, 0), 209b7482f52SPhilipp Zabel }; 210b7482f52SPhilipp Zabel 211b7482f52SPhilipp Zabel /* 212b7482f52SPhilipp Zabel * from -72 dB in 1.5 dB steps (6 dB steps really), 213b7482f52SPhilipp Zabel * from -66 dB in 0.75 dB steps (3 dB steps really), 214b7482f52SPhilipp Zabel * from -60 dB in 0.5 dB steps (2 dB steps really) and 215b7482f52SPhilipp Zabel * from -46 dB in 0.25 dB steps 216b7482f52SPhilipp Zabel */ 217b7482f52SPhilipp Zabel static const unsigned int vc_tlv[] = { 218b7482f52SPhilipp Zabel TLV_DB_RANGE_HEAD(4), 219b7482f52SPhilipp Zabel 0, 7, TLV_DB_SCALE_ITEM(-7800, 150, 1), 220b7482f52SPhilipp Zabel 8, 15, TLV_DB_SCALE_ITEM(-6600, 75, 0), 221b7482f52SPhilipp Zabel 16, 43, TLV_DB_SCALE_ITEM(-6000, 50, 0), 222b7482f52SPhilipp Zabel 44, 228, TLV_DB_SCALE_ITEM(-4600, 25, 0), 223b7482f52SPhilipp Zabel }; 224b7482f52SPhilipp Zabel 225b7482f52SPhilipp Zabel /* from 0 to 6 dB in 2 dB steps if SPF mode != flat */ 226b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(tr_tlv, 0, 200, 0); 227b7482f52SPhilipp Zabel 228b7482f52SPhilipp Zabel /* from 0 to 24 dB in 2 dB steps, if SPF mode == maximum, otherwise cuts 229b7482f52SPhilipp Zabel * off at 18 dB max) */ 230b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(bb_tlv, 0, 200, 0); 231b7482f52SPhilipp Zabel 232b7482f52SPhilipp Zabel /* from -63 to 24 dB in 0.5 dB steps (-128...48) */ 233b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(dec_tlv, -6400, 50, 1); 234b7482f52SPhilipp Zabel 235b7482f52SPhilipp Zabel /* from 0 to 24 dB in 3 dB steps */ 236b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); 237b7482f52SPhilipp Zabel 238b7482f52SPhilipp Zabel /* from 0 to 30 dB in 2 dB steps */ 239b7482f52SPhilipp Zabel static DECLARE_TLV_DB_SCALE(vga_tlv, 0, 200, 0); 240b7482f52SPhilipp Zabel 241b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_snd_controls[] = { 242b7482f52SPhilipp Zabel SOC_DOUBLE_TLV("Analog Mixer Volume", UDA1380_AMIX, 0, 8, 44, 1, amix_tlv), /* AVCR, AVCL */ 243b7482f52SPhilipp Zabel SOC_DOUBLE_TLV("Master Playback Volume", UDA1380_MVOL, 0, 8, 252, 1, mvol_tlv), /* MVCL, MVCR */ 244b7482f52SPhilipp Zabel SOC_SINGLE_TLV("ADC Playback Volume", UDA1380_MIXVOL, 8, 228, 1, vc_tlv), /* VC2 */ 245b7482f52SPhilipp Zabel SOC_SINGLE_TLV("PCM Playback Volume", UDA1380_MIXVOL, 0, 228, 1, vc_tlv), /* VC1 */ 246b7482f52SPhilipp Zabel SOC_ENUM("Sound Processing Filter", uda1380_spf_enum), /* M */ 247b7482f52SPhilipp Zabel SOC_DOUBLE_TLV("Tone Control - Treble", UDA1380_MODE, 4, 12, 3, 0, tr_tlv), /* TRL, TRR */ 248b7482f52SPhilipp Zabel SOC_DOUBLE_TLV("Tone Control - Bass", UDA1380_MODE, 0, 8, 15, 0, bb_tlv), /* BBL, BBR */ 249b7482f52SPhilipp Zabel /**/ SOC_SINGLE("Master Playback Switch", UDA1380_DEEMP, 14, 1, 1), /* MTM */ 250b7482f52SPhilipp Zabel SOC_SINGLE("ADC Playback Switch", UDA1380_DEEMP, 11, 1, 1), /* MT2 from decimation filter */ 251b7482f52SPhilipp Zabel SOC_ENUM("ADC Playback De-emphasis", uda1380_deemp_enum[0]), /* DE2 */ 252b7482f52SPhilipp Zabel SOC_SINGLE("PCM Playback Switch", UDA1380_DEEMP, 3, 1, 1), /* MT1, from digital data input */ 253b7482f52SPhilipp Zabel SOC_ENUM("PCM Playback De-emphasis", uda1380_deemp_enum[1]), /* DE1 */ 254b7482f52SPhilipp Zabel SOC_SINGLE("DAC Polarity inverting Switch", UDA1380_MIXER, 15, 1, 0), /* DA_POL_INV */ 255b7482f52SPhilipp Zabel SOC_ENUM("Noise Shaper", uda1380_sel_ns_enum), /* SEL_NS */ 256b7482f52SPhilipp Zabel SOC_ENUM("Digital Mixer Signal Control", uda1380_mix_enum), /* MIX_POS, MIX */ 257b7482f52SPhilipp Zabel SOC_SINGLE("Silence Switch", UDA1380_MIXER, 7, 1, 0), /* SILENCE, force DAC output to silence */ 258b7482f52SPhilipp Zabel SOC_SINGLE("Silence Detector Switch", UDA1380_MIXER, 6, 1, 0), /* SDET_ON */ 259b7482f52SPhilipp Zabel SOC_ENUM("Silence Detector Setting", uda1380_sdet_enum), /* SD_VALUE */ 260b7482f52SPhilipp Zabel SOC_ENUM("Oversampling Input", uda1380_os_enum), /* OS */ 261b7482f52SPhilipp Zabel SOC_DOUBLE_S8_TLV("ADC Capture Volume", UDA1380_DEC, -128, 48, dec_tlv), /* ML_DEC, MR_DEC */ 262b7482f52SPhilipp Zabel /**/ SOC_SINGLE("ADC Capture Switch", UDA1380_PGA, 15, 1, 1), /* MT_ADC */ 263b7482f52SPhilipp Zabel SOC_DOUBLE_TLV("Line Capture Volume", UDA1380_PGA, 0, 8, 8, 0, pga_tlv), /* PGA_GAINCTRLL, PGA_GAINCTRLR */ 264b7482f52SPhilipp Zabel SOC_SINGLE("ADC Polarity inverting Switch", UDA1380_ADC, 12, 1, 0), /* ADCPOL_INV */ 265b7482f52SPhilipp Zabel SOC_SINGLE_TLV("Mic Capture Volume", UDA1380_ADC, 8, 15, 0, vga_tlv), /* VGA_CTRL */ 266b7482f52SPhilipp Zabel SOC_SINGLE("DC Filter Bypass Switch", UDA1380_ADC, 1, 1, 0), /* SKIP_DCFIL (before decimator) */ 267b7482f52SPhilipp Zabel SOC_SINGLE("DC Filter Enable Switch", UDA1380_ADC, 0, 1, 0), /* EN_DCFIL (at output of decimator) */ 268b7482f52SPhilipp Zabel SOC_SINGLE("AGC Timing", UDA1380_AGC, 8, 7, 0), /* TODO: enum, see table 62 */ 269b7482f52SPhilipp Zabel SOC_SINGLE("AGC Target level", UDA1380_AGC, 2, 3, 1), /* AGC_LEVEL */ 270b7482f52SPhilipp Zabel /* -5.5, -8, -11.5, -14 dBFS */ 271b7482f52SPhilipp Zabel SOC_SINGLE("AGC Switch", UDA1380_AGC, 0, 1, 0), 272b7482f52SPhilipp Zabel }; 273b7482f52SPhilipp Zabel 274b7482f52SPhilipp Zabel /* add non dapm controls */ 275b7482f52SPhilipp Zabel static int uda1380_add_controls(struct snd_soc_codec *codec) 276b7482f52SPhilipp Zabel { 277b7482f52SPhilipp Zabel int err, i; 278b7482f52SPhilipp Zabel 279b7482f52SPhilipp Zabel for (i = 0; i < ARRAY_SIZE(uda1380_snd_controls); i++) { 280b7482f52SPhilipp Zabel err = snd_ctl_add(codec->card, 281b7482f52SPhilipp Zabel snd_soc_cnew(&uda1380_snd_controls[i], codec, NULL)); 282b7482f52SPhilipp Zabel if (err < 0) 283b7482f52SPhilipp Zabel return err; 284b7482f52SPhilipp Zabel } 285b7482f52SPhilipp Zabel 286b7482f52SPhilipp Zabel return 0; 287b7482f52SPhilipp Zabel } 288b7482f52SPhilipp Zabel 289b7482f52SPhilipp Zabel /* Input mux */ 290b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_input_mux_control = 291b7482f52SPhilipp Zabel SOC_DAPM_ENUM("Route", uda1380_input_sel_enum); 292b7482f52SPhilipp Zabel 293b7482f52SPhilipp Zabel /* Output mux */ 294b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_output_mux_control = 295b7482f52SPhilipp Zabel SOC_DAPM_ENUM("Route", uda1380_output_sel_enum); 296b7482f52SPhilipp Zabel 297b7482f52SPhilipp Zabel /* Capture mux */ 298b7482f52SPhilipp Zabel static const struct snd_kcontrol_new uda1380_capture_mux_control = 299b7482f52SPhilipp Zabel SOC_DAPM_ENUM("Route", uda1380_capture_sel_enum); 300b7482f52SPhilipp Zabel 301b7482f52SPhilipp Zabel 302b7482f52SPhilipp Zabel static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { 303b7482f52SPhilipp Zabel SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, 304b7482f52SPhilipp Zabel &uda1380_input_mux_control), 305b7482f52SPhilipp Zabel SND_SOC_DAPM_MUX("Output Mux", SND_SOC_NOPM, 0, 0, 306b7482f52SPhilipp Zabel &uda1380_output_mux_control), 307b7482f52SPhilipp Zabel SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, 308b7482f52SPhilipp Zabel &uda1380_capture_mux_control), 309b7482f52SPhilipp Zabel SND_SOC_DAPM_PGA("Left PGA", UDA1380_PM, 3, 0, NULL, 0), 310b7482f52SPhilipp Zabel SND_SOC_DAPM_PGA("Right PGA", UDA1380_PM, 1, 0, NULL, 0), 311b7482f52SPhilipp Zabel SND_SOC_DAPM_PGA("Mic LNA", UDA1380_PM, 4, 0, NULL, 0), 312b7482f52SPhilipp Zabel SND_SOC_DAPM_ADC("Left ADC", "Left Capture", UDA1380_PM, 2, 0), 313b7482f52SPhilipp Zabel SND_SOC_DAPM_ADC("Right ADC", "Right Capture", UDA1380_PM, 0, 0), 314b7482f52SPhilipp Zabel SND_SOC_DAPM_INPUT("VINM"), 315b7482f52SPhilipp Zabel SND_SOC_DAPM_INPUT("VINL"), 316b7482f52SPhilipp Zabel SND_SOC_DAPM_INPUT("VINR"), 317b7482f52SPhilipp Zabel SND_SOC_DAPM_MIXER("Analog Mixer", UDA1380_PM, 6, 0, NULL, 0), 318b7482f52SPhilipp Zabel SND_SOC_DAPM_OUTPUT("VOUTLHP"), 319b7482f52SPhilipp Zabel SND_SOC_DAPM_OUTPUT("VOUTRHP"), 320b7482f52SPhilipp Zabel SND_SOC_DAPM_OUTPUT("VOUTL"), 321b7482f52SPhilipp Zabel SND_SOC_DAPM_OUTPUT("VOUTR"), 322b7482f52SPhilipp Zabel SND_SOC_DAPM_DAC("DAC", "Playback", UDA1380_PM, 10, 0), 323b7482f52SPhilipp Zabel SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0), 324b7482f52SPhilipp Zabel }; 325b7482f52SPhilipp Zabel 326b7482f52SPhilipp Zabel static const struct snd_soc_dapm_route audio_map[] = { 327b7482f52SPhilipp Zabel 328b7482f52SPhilipp Zabel /* output mux */ 329b7482f52SPhilipp Zabel {"HeadPhone Driver", NULL, "Output Mux"}, 330b7482f52SPhilipp Zabel {"VOUTR", NULL, "Output Mux"}, 331b7482f52SPhilipp Zabel {"VOUTL", NULL, "Output Mux"}, 332b7482f52SPhilipp Zabel 333b7482f52SPhilipp Zabel {"Analog Mixer", NULL, "VINR"}, 334b7482f52SPhilipp Zabel {"Analog Mixer", NULL, "VINL"}, 335b7482f52SPhilipp Zabel {"Analog Mixer", NULL, "DAC"}, 336b7482f52SPhilipp Zabel 337b7482f52SPhilipp Zabel {"Output Mux", "DAC", "DAC"}, 338b7482f52SPhilipp Zabel {"Output Mux", "Analog Mixer", "Analog Mixer"}, 339b7482f52SPhilipp Zabel 340b7482f52SPhilipp Zabel /* {"DAC", "Digital Mixer", "I2S" } */ 341b7482f52SPhilipp Zabel 342b7482f52SPhilipp Zabel /* headphone driver */ 343b7482f52SPhilipp Zabel {"VOUTLHP", NULL, "HeadPhone Driver"}, 344b7482f52SPhilipp Zabel {"VOUTRHP", NULL, "HeadPhone Driver"}, 345b7482f52SPhilipp Zabel 346b7482f52SPhilipp Zabel /* input mux */ 347b7482f52SPhilipp Zabel {"Left ADC", NULL, "Input Mux"}, 348b7482f52SPhilipp Zabel {"Input Mux", "Mic", "Mic LNA"}, 349b7482f52SPhilipp Zabel {"Input Mux", "Mic + Line R", "Mic LNA"}, 350b7482f52SPhilipp Zabel {"Input Mux", "Line L", "Left PGA"}, 351b7482f52SPhilipp Zabel {"Input Mux", "Line", "Left PGA"}, 352b7482f52SPhilipp Zabel 353b7482f52SPhilipp Zabel /* right input */ 354b7482f52SPhilipp Zabel {"Right ADC", "Mic + Line R", "Right PGA"}, 355b7482f52SPhilipp Zabel {"Right ADC", "Line", "Right PGA"}, 356b7482f52SPhilipp Zabel 357b7482f52SPhilipp Zabel /* inputs */ 358b7482f52SPhilipp Zabel {"Mic LNA", NULL, "VINM"}, 359b7482f52SPhilipp Zabel {"Left PGA", NULL, "VINL"}, 360b7482f52SPhilipp Zabel {"Right PGA", NULL, "VINR"}, 361b7482f52SPhilipp Zabel }; 362b7482f52SPhilipp Zabel 363b7482f52SPhilipp Zabel static int uda1380_add_widgets(struct snd_soc_codec *codec) 364b7482f52SPhilipp Zabel { 365b7482f52SPhilipp Zabel snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 366b7482f52SPhilipp Zabel ARRAY_SIZE(uda1380_dapm_widgets)); 367b7482f52SPhilipp Zabel 368b7482f52SPhilipp Zabel snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 369b7482f52SPhilipp Zabel 370b7482f52SPhilipp Zabel snd_soc_dapm_new_widgets(codec); 371b7482f52SPhilipp Zabel return 0; 372b7482f52SPhilipp Zabel } 373b7482f52SPhilipp Zabel 374e550e17fSLiam Girdwood static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai, 375b7482f52SPhilipp Zabel unsigned int fmt) 376b7482f52SPhilipp Zabel { 377b7482f52SPhilipp Zabel struct snd_soc_codec *codec = codec_dai->codec; 378b7482f52SPhilipp Zabel int iface; 379b7482f52SPhilipp Zabel 380b7482f52SPhilipp Zabel /* set up DAI based upon fmt */ 381b7482f52SPhilipp Zabel iface = uda1380_read_reg_cache(codec, UDA1380_IFACE); 382b7482f52SPhilipp Zabel iface &= ~(R01_SFORI_MASK | R01_SIM | R01_SFORO_MASK); 383b7482f52SPhilipp Zabel 384b7482f52SPhilipp Zabel /* FIXME: how to select I2S for DATAO and MSB for DATAI correctly? */ 385b7482f52SPhilipp Zabel switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 386b7482f52SPhilipp Zabel case SND_SOC_DAIFMT_I2S: 387b7482f52SPhilipp Zabel iface |= R01_SFORI_I2S | R01_SFORO_I2S; 388b7482f52SPhilipp Zabel break; 389b7482f52SPhilipp Zabel case SND_SOC_DAIFMT_LSB: 390b7482f52SPhilipp Zabel iface |= R01_SFORI_LSB16 | R01_SFORO_I2S; 391b7482f52SPhilipp Zabel break; 392b7482f52SPhilipp Zabel case SND_SOC_DAIFMT_MSB: 393b7482f52SPhilipp Zabel iface |= R01_SFORI_MSB | R01_SFORO_I2S; 394b7482f52SPhilipp Zabel } 395b7482f52SPhilipp Zabel 396b7482f52SPhilipp Zabel if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) == SND_SOC_DAIFMT_CBM_CFM) 397b7482f52SPhilipp Zabel iface |= R01_SIM; 398b7482f52SPhilipp Zabel 399b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_IFACE, iface); 400b7482f52SPhilipp Zabel 401b7482f52SPhilipp Zabel return 0; 402b7482f52SPhilipp Zabel } 403b7482f52SPhilipp Zabel 404b7482f52SPhilipp Zabel /* 405b7482f52SPhilipp Zabel * Flush reg cache 406b7482f52SPhilipp Zabel * We can only write the interpolator and decimator registers 407b7482f52SPhilipp Zabel * when the DAI is being clocked by the CPU DAI. It's up to the 408b7482f52SPhilipp Zabel * machine and cpu DAI driver to do this before we are called. 409b7482f52SPhilipp Zabel */ 410dee89c4dSMark Brown static int uda1380_pcm_prepare(struct snd_pcm_substream *substream, 411dee89c4dSMark Brown struct snd_soc_dai *dai) 412b7482f52SPhilipp Zabel { 413b7482f52SPhilipp Zabel struct snd_soc_pcm_runtime *rtd = substream->private_data; 414b7482f52SPhilipp Zabel struct snd_soc_device *socdev = rtd->socdev; 415b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 416b7482f52SPhilipp Zabel int reg, reg_start, reg_end, clk; 417b7482f52SPhilipp Zabel 418b7482f52SPhilipp Zabel if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 419b7482f52SPhilipp Zabel reg_start = UDA1380_MVOL; 420b7482f52SPhilipp Zabel reg_end = UDA1380_MIXER; 421b7482f52SPhilipp Zabel } else { 422b7482f52SPhilipp Zabel reg_start = UDA1380_DEC; 423b7482f52SPhilipp Zabel reg_end = UDA1380_AGC; 424b7482f52SPhilipp Zabel } 425b7482f52SPhilipp Zabel 426b7482f52SPhilipp Zabel /* FIXME disable DAC_CLK */ 427b7482f52SPhilipp Zabel clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 428b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, clk & ~R00_DAC_CLK); 429b7482f52SPhilipp Zabel 430b7482f52SPhilipp Zabel for (reg = reg_start; reg <= reg_end; reg++) { 431b7482f52SPhilipp Zabel pr_debug("uda1380: flush reg %x val %x:", reg, 432b7482f52SPhilipp Zabel uda1380_read_reg_cache(codec, reg)); 433b7482f52SPhilipp Zabel uda1380_write(codec, reg, uda1380_read_reg_cache(codec, reg)); 434b7482f52SPhilipp Zabel } 435b7482f52SPhilipp Zabel 436b7482f52SPhilipp Zabel /* FIXME enable DAC_CLK */ 437b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, clk | R00_DAC_CLK); 438b7482f52SPhilipp Zabel 439b7482f52SPhilipp Zabel return 0; 440b7482f52SPhilipp Zabel } 441b7482f52SPhilipp Zabel 442b7482f52SPhilipp Zabel static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, 443dee89c4dSMark Brown struct snd_pcm_hw_params *params, 444dee89c4dSMark Brown struct snd_soc_dai *dai) 445b7482f52SPhilipp Zabel { 446b7482f52SPhilipp Zabel struct snd_soc_pcm_runtime *rtd = substream->private_data; 447b7482f52SPhilipp Zabel struct snd_soc_device *socdev = rtd->socdev; 448b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 449b7482f52SPhilipp Zabel u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 450b7482f52SPhilipp Zabel 451b7482f52SPhilipp Zabel /* set WSPLL power and divider if running from this clock */ 452b7482f52SPhilipp Zabel if (clk & R00_DAC_CLK) { 453b7482f52SPhilipp Zabel int rate = params_rate(params); 454b7482f52SPhilipp Zabel u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM); 455b7482f52SPhilipp Zabel clk &= ~0x3; /* clear SEL_LOOP_DIV */ 456b7482f52SPhilipp Zabel switch (rate) { 457b7482f52SPhilipp Zabel case 6250 ... 12500: 458b7482f52SPhilipp Zabel clk |= 0x0; 459b7482f52SPhilipp Zabel break; 460b7482f52SPhilipp Zabel case 12501 ... 25000: 461b7482f52SPhilipp Zabel clk |= 0x1; 462b7482f52SPhilipp Zabel break; 463b7482f52SPhilipp Zabel case 25001 ... 50000: 464b7482f52SPhilipp Zabel clk |= 0x2; 465b7482f52SPhilipp Zabel break; 466b7482f52SPhilipp Zabel case 50001 ... 100000: 467b7482f52SPhilipp Zabel clk |= 0x3; 468b7482f52SPhilipp Zabel break; 469b7482f52SPhilipp Zabel } 470b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_PM, R02_PON_PLL | pm); 471b7482f52SPhilipp Zabel } 472b7482f52SPhilipp Zabel 473b7482f52SPhilipp Zabel if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 474b7482f52SPhilipp Zabel clk |= R00_EN_DAC | R00_EN_INT; 475b7482f52SPhilipp Zabel else 476b7482f52SPhilipp Zabel clk |= R00_EN_ADC | R00_EN_DEC; 477b7482f52SPhilipp Zabel 478b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, clk); 479b7482f52SPhilipp Zabel return 0; 480b7482f52SPhilipp Zabel } 481b7482f52SPhilipp Zabel 482dee89c4dSMark Brown static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, 483dee89c4dSMark Brown struct snd_soc_dai *dai) 484b7482f52SPhilipp Zabel { 485b7482f52SPhilipp Zabel struct snd_soc_pcm_runtime *rtd = substream->private_data; 486b7482f52SPhilipp Zabel struct snd_soc_device *socdev = rtd->socdev; 487b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 488b7482f52SPhilipp Zabel u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 489b7482f52SPhilipp Zabel 490b7482f52SPhilipp Zabel /* shut down WSPLL power if running from this clock */ 491b7482f52SPhilipp Zabel if (clk & R00_DAC_CLK) { 492b7482f52SPhilipp Zabel u16 pm = uda1380_read_reg_cache(codec, UDA1380_PM); 493b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_PM, ~R02_PON_PLL & pm); 494b7482f52SPhilipp Zabel } 495b7482f52SPhilipp Zabel 496b7482f52SPhilipp Zabel if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 497b7482f52SPhilipp Zabel clk &= ~(R00_EN_DAC | R00_EN_INT); 498b7482f52SPhilipp Zabel else 499b7482f52SPhilipp Zabel clk &= ~(R00_EN_ADC | R00_EN_DEC); 500b7482f52SPhilipp Zabel 501b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, clk); 502b7482f52SPhilipp Zabel } 503b7482f52SPhilipp Zabel 504e550e17fSLiam Girdwood static int uda1380_mute(struct snd_soc_dai *codec_dai, int mute) 505b7482f52SPhilipp Zabel { 506b7482f52SPhilipp Zabel struct snd_soc_codec *codec = codec_dai->codec; 507b7482f52SPhilipp Zabel u16 mute_reg = uda1380_read_reg_cache(codec, UDA1380_DEEMP) & ~R13_MTM; 508b7482f52SPhilipp Zabel 509b7482f52SPhilipp Zabel /* FIXME: mute(codec,0) is called when the magician clock is already 510b7482f52SPhilipp Zabel * set to WSPLL, but for some unknown reason writing to interpolator 511b7482f52SPhilipp Zabel * registers works only when clocked by SYSCLK */ 512b7482f52SPhilipp Zabel u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); 513b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, ~R00_DAC_CLK & clk); 514b7482f52SPhilipp Zabel if (mute) 515b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_DEEMP, mute_reg | R13_MTM); 516b7482f52SPhilipp Zabel else 517b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_DEEMP, mute_reg); 518b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, clk); 519b7482f52SPhilipp Zabel return 0; 520b7482f52SPhilipp Zabel } 521b7482f52SPhilipp Zabel 522b7482f52SPhilipp Zabel static int uda1380_set_bias_level(struct snd_soc_codec *codec, 523b7482f52SPhilipp Zabel enum snd_soc_bias_level level) 524b7482f52SPhilipp Zabel { 525b7482f52SPhilipp Zabel int pm = uda1380_read_reg_cache(codec, UDA1380_PM); 526b7482f52SPhilipp Zabel 527b7482f52SPhilipp Zabel switch (level) { 528b7482f52SPhilipp Zabel case SND_SOC_BIAS_ON: 529b7482f52SPhilipp Zabel case SND_SOC_BIAS_PREPARE: 530b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); 531b7482f52SPhilipp Zabel break; 532b7482f52SPhilipp Zabel case SND_SOC_BIAS_STANDBY: 533b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_PM, R02_PON_BIAS); 534b7482f52SPhilipp Zabel break; 535b7482f52SPhilipp Zabel case SND_SOC_BIAS_OFF: 536b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_PM, 0x0); 537b7482f52SPhilipp Zabel break; 538b7482f52SPhilipp Zabel } 539b7482f52SPhilipp Zabel codec->bias_level = level; 540b7482f52SPhilipp Zabel return 0; 541b7482f52SPhilipp Zabel } 542b7482f52SPhilipp Zabel 543b7482f52SPhilipp Zabel #define UDA1380_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ 544b7482f52SPhilipp Zabel SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ 545b7482f52SPhilipp Zabel SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 546b7482f52SPhilipp Zabel 547e550e17fSLiam Girdwood struct snd_soc_dai uda1380_dai[] = { 548b7482f52SPhilipp Zabel { 549b7482f52SPhilipp Zabel .name = "UDA1380", 550b7482f52SPhilipp Zabel .playback = { 551b7482f52SPhilipp Zabel .stream_name = "Playback", 552b7482f52SPhilipp Zabel .channels_min = 1, 553b7482f52SPhilipp Zabel .channels_max = 2, 554b7482f52SPhilipp Zabel .rates = UDA1380_RATES, 555b7482f52SPhilipp Zabel .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 556b7482f52SPhilipp Zabel .capture = { 557b7482f52SPhilipp Zabel .stream_name = "Capture", 558b7482f52SPhilipp Zabel .channels_min = 1, 559b7482f52SPhilipp Zabel .channels_max = 2, 560b7482f52SPhilipp Zabel .rates = UDA1380_RATES, 561b7482f52SPhilipp Zabel .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 562b7482f52SPhilipp Zabel .ops = { 563b7482f52SPhilipp Zabel .hw_params = uda1380_pcm_hw_params, 564b7482f52SPhilipp Zabel .shutdown = uda1380_pcm_shutdown, 565b7482f52SPhilipp Zabel .prepare = uda1380_pcm_prepare, 566b7482f52SPhilipp Zabel .digital_mute = uda1380_mute, 567b7482f52SPhilipp Zabel .set_fmt = uda1380_set_dai_fmt, 568b7482f52SPhilipp Zabel }, 569b7482f52SPhilipp Zabel }, 570b7482f52SPhilipp Zabel { /* playback only - dual interface */ 571b7482f52SPhilipp Zabel .name = "UDA1380", 572b7482f52SPhilipp Zabel .playback = { 573b7482f52SPhilipp Zabel .stream_name = "Playback", 574b7482f52SPhilipp Zabel .channels_min = 1, 575b7482f52SPhilipp Zabel .channels_max = 2, 576b7482f52SPhilipp Zabel .rates = UDA1380_RATES, 577b7482f52SPhilipp Zabel .formats = SNDRV_PCM_FMTBIT_S16_LE, 578b7482f52SPhilipp Zabel }, 579b7482f52SPhilipp Zabel .ops = { 580b7482f52SPhilipp Zabel .hw_params = uda1380_pcm_hw_params, 581b7482f52SPhilipp Zabel .shutdown = uda1380_pcm_shutdown, 582b7482f52SPhilipp Zabel .prepare = uda1380_pcm_prepare, 583b7482f52SPhilipp Zabel .digital_mute = uda1380_mute, 584b7482f52SPhilipp Zabel .set_fmt = uda1380_set_dai_fmt, 585b7482f52SPhilipp Zabel }, 586b7482f52SPhilipp Zabel }, 587b7482f52SPhilipp Zabel { /* capture only - dual interface*/ 588b7482f52SPhilipp Zabel .name = "UDA1380", 589b7482f52SPhilipp Zabel .capture = { 590b7482f52SPhilipp Zabel .stream_name = "Capture", 591b7482f52SPhilipp Zabel .channels_min = 1, 592b7482f52SPhilipp Zabel .channels_max = 2, 593b7482f52SPhilipp Zabel .rates = UDA1380_RATES, 594b7482f52SPhilipp Zabel .formats = SNDRV_PCM_FMTBIT_S16_LE, 595b7482f52SPhilipp Zabel }, 596b7482f52SPhilipp Zabel .ops = { 597b7482f52SPhilipp Zabel .hw_params = uda1380_pcm_hw_params, 598b7482f52SPhilipp Zabel .shutdown = uda1380_pcm_shutdown, 599b7482f52SPhilipp Zabel .prepare = uda1380_pcm_prepare, 600b7482f52SPhilipp Zabel .set_fmt = uda1380_set_dai_fmt, 601b7482f52SPhilipp Zabel }, 602b7482f52SPhilipp Zabel }, 603b7482f52SPhilipp Zabel }; 604b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(uda1380_dai); 605b7482f52SPhilipp Zabel 606b7482f52SPhilipp Zabel static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) 607b7482f52SPhilipp Zabel { 608b7482f52SPhilipp Zabel struct snd_soc_device *socdev = platform_get_drvdata(pdev); 609b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 610b7482f52SPhilipp Zabel 611b7482f52SPhilipp Zabel uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 612b7482f52SPhilipp Zabel return 0; 613b7482f52SPhilipp Zabel } 614b7482f52SPhilipp Zabel 615b7482f52SPhilipp Zabel static int uda1380_resume(struct platform_device *pdev) 616b7482f52SPhilipp Zabel { 617b7482f52SPhilipp Zabel struct snd_soc_device *socdev = platform_get_drvdata(pdev); 618b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 619b7482f52SPhilipp Zabel int i; 620b7482f52SPhilipp Zabel u8 data[2]; 621b7482f52SPhilipp Zabel u16 *cache = codec->reg_cache; 622b7482f52SPhilipp Zabel 623b7482f52SPhilipp Zabel /* Sync reg_cache with the hardware */ 624b7482f52SPhilipp Zabel for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) { 625b7482f52SPhilipp Zabel data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 626b7482f52SPhilipp Zabel data[1] = cache[i] & 0x00ff; 627b7482f52SPhilipp Zabel codec->hw_write(codec->control_data, data, 2); 628b7482f52SPhilipp Zabel } 629b7482f52SPhilipp Zabel uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 630b7482f52SPhilipp Zabel uda1380_set_bias_level(codec, codec->suspend_bias_level); 631b7482f52SPhilipp Zabel return 0; 632b7482f52SPhilipp Zabel } 633b7482f52SPhilipp Zabel 634b7482f52SPhilipp Zabel /* 635b7482f52SPhilipp Zabel * initialise the UDA1380 driver 636b7482f52SPhilipp Zabel * register mixer and dsp interfaces with the kernel 637b7482f52SPhilipp Zabel */ 638b7482f52SPhilipp Zabel static int uda1380_init(struct snd_soc_device *socdev, int dac_clk) 639b7482f52SPhilipp Zabel { 640b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 641b7482f52SPhilipp Zabel int ret = 0; 642b7482f52SPhilipp Zabel 643b7482f52SPhilipp Zabel codec->name = "UDA1380"; 644b7482f52SPhilipp Zabel codec->owner = THIS_MODULE; 645b7482f52SPhilipp Zabel codec->read = uda1380_read_reg_cache; 646b7482f52SPhilipp Zabel codec->write = uda1380_write; 647b7482f52SPhilipp Zabel codec->set_bias_level = uda1380_set_bias_level; 648b7482f52SPhilipp Zabel codec->dai = uda1380_dai; 649b7482f52SPhilipp Zabel codec->num_dai = ARRAY_SIZE(uda1380_dai); 650b7482f52SPhilipp Zabel codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg), 651b7482f52SPhilipp Zabel GFP_KERNEL); 652b7482f52SPhilipp Zabel if (codec->reg_cache == NULL) 653b7482f52SPhilipp Zabel return -ENOMEM; 6548ddd4407SMark Brown codec->reg_cache_size = ARRAY_SIZE(uda1380_reg); 6558ddd4407SMark Brown codec->reg_cache_step = 1; 656b7482f52SPhilipp Zabel uda1380_reset(codec); 657b7482f52SPhilipp Zabel 658b7482f52SPhilipp Zabel /* register pcms */ 659b7482f52SPhilipp Zabel ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 660b7482f52SPhilipp Zabel if (ret < 0) { 661b7482f52SPhilipp Zabel pr_err("uda1380: failed to create pcms\n"); 662b7482f52SPhilipp Zabel goto pcm_err; 663b7482f52SPhilipp Zabel } 664b7482f52SPhilipp Zabel 665b7482f52SPhilipp Zabel /* power on device */ 666b7482f52SPhilipp Zabel uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 667b7482f52SPhilipp Zabel /* set clock input */ 668b7482f52SPhilipp Zabel switch (dac_clk) { 669b7482f52SPhilipp Zabel case UDA1380_DAC_CLK_SYSCLK: 670b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, 0); 671b7482f52SPhilipp Zabel break; 672b7482f52SPhilipp Zabel case UDA1380_DAC_CLK_WSPLL: 673b7482f52SPhilipp Zabel uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK); 674b7482f52SPhilipp Zabel break; 675b7482f52SPhilipp Zabel } 676b7482f52SPhilipp Zabel 677b7482f52SPhilipp Zabel /* uda1380 init */ 678b7482f52SPhilipp Zabel uda1380_add_controls(codec); 679b7482f52SPhilipp Zabel uda1380_add_widgets(codec); 680968a6025SMark Brown ret = snd_soc_init_card(socdev); 681b7482f52SPhilipp Zabel if (ret < 0) { 682b7482f52SPhilipp Zabel pr_err("uda1380: failed to register card\n"); 683b7482f52SPhilipp Zabel goto card_err; 684b7482f52SPhilipp Zabel } 685b7482f52SPhilipp Zabel 686b7482f52SPhilipp Zabel return ret; 687b7482f52SPhilipp Zabel 688b7482f52SPhilipp Zabel card_err: 689b7482f52SPhilipp Zabel snd_soc_free_pcms(socdev); 690b7482f52SPhilipp Zabel snd_soc_dapm_free(socdev); 691b7482f52SPhilipp Zabel pcm_err: 692b7482f52SPhilipp Zabel kfree(codec->reg_cache); 693b7482f52SPhilipp Zabel return ret; 694b7482f52SPhilipp Zabel } 695b7482f52SPhilipp Zabel 696b7482f52SPhilipp Zabel static struct snd_soc_device *uda1380_socdev; 697b7482f52SPhilipp Zabel 698b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 699b7482f52SPhilipp Zabel 70088fc39d7SJean Delvare static int uda1380_i2c_probe(struct i2c_client *i2c, 70188fc39d7SJean Delvare const struct i2c_device_id *id) 702b7482f52SPhilipp Zabel { 703b7482f52SPhilipp Zabel struct snd_soc_device *socdev = uda1380_socdev; 704b7482f52SPhilipp Zabel struct uda1380_setup_data *setup = socdev->codec_data; 705b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 706b7482f52SPhilipp Zabel int ret; 707b7482f52SPhilipp Zabel 708b7482f52SPhilipp Zabel i2c_set_clientdata(i2c, codec); 709b7482f52SPhilipp Zabel codec->control_data = i2c; 710b7482f52SPhilipp Zabel 711b7482f52SPhilipp Zabel ret = uda1380_init(socdev, setup->dac_clk); 71288fc39d7SJean Delvare if (ret < 0) 713b7482f52SPhilipp Zabel pr_err("uda1380: failed to initialise UDA1380\n"); 714b7482f52SPhilipp Zabel 715b7482f52SPhilipp Zabel return ret; 716b7482f52SPhilipp Zabel } 717b7482f52SPhilipp Zabel 71888fc39d7SJean Delvare static int uda1380_i2c_remove(struct i2c_client *client) 719b7482f52SPhilipp Zabel { 720b7482f52SPhilipp Zabel struct snd_soc_codec *codec = i2c_get_clientdata(client); 721b7482f52SPhilipp Zabel kfree(codec->reg_cache); 722b7482f52SPhilipp Zabel return 0; 723b7482f52SPhilipp Zabel } 724b7482f52SPhilipp Zabel 72588fc39d7SJean Delvare static const struct i2c_device_id uda1380_i2c_id[] = { 72688fc39d7SJean Delvare { "uda1380", 0 }, 72788fc39d7SJean Delvare { } 72888fc39d7SJean Delvare }; 72988fc39d7SJean Delvare MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); 730b7482f52SPhilipp Zabel 731b7482f52SPhilipp Zabel static struct i2c_driver uda1380_i2c_driver = { 732b7482f52SPhilipp Zabel .driver = { 733b7482f52SPhilipp Zabel .name = "UDA1380 I2C Codec", 734b7482f52SPhilipp Zabel .owner = THIS_MODULE, 735b7482f52SPhilipp Zabel }, 73688fc39d7SJean Delvare .probe = uda1380_i2c_probe, 73788fc39d7SJean Delvare .remove = uda1380_i2c_remove, 73888fc39d7SJean Delvare .id_table = uda1380_i2c_id, 739b7482f52SPhilipp Zabel }; 740b7482f52SPhilipp Zabel 74188fc39d7SJean Delvare static int uda1380_add_i2c_device(struct platform_device *pdev, 74288fc39d7SJean Delvare const struct uda1380_setup_data *setup) 74388fc39d7SJean Delvare { 74488fc39d7SJean Delvare struct i2c_board_info info; 74588fc39d7SJean Delvare struct i2c_adapter *adapter; 74688fc39d7SJean Delvare struct i2c_client *client; 74788fc39d7SJean Delvare int ret; 74888fc39d7SJean Delvare 74988fc39d7SJean Delvare ret = i2c_add_driver(&uda1380_i2c_driver); 75088fc39d7SJean Delvare if (ret != 0) { 75188fc39d7SJean Delvare dev_err(&pdev->dev, "can't add i2c driver\n"); 75288fc39d7SJean Delvare return ret; 75388fc39d7SJean Delvare } 75488fc39d7SJean Delvare 75588fc39d7SJean Delvare memset(&info, 0, sizeof(struct i2c_board_info)); 75688fc39d7SJean Delvare info.addr = setup->i2c_address; 75788fc39d7SJean Delvare strlcpy(info.type, "uda1380", I2C_NAME_SIZE); 75888fc39d7SJean Delvare 75988fc39d7SJean Delvare adapter = i2c_get_adapter(setup->i2c_bus); 76088fc39d7SJean Delvare if (!adapter) { 76188fc39d7SJean Delvare dev_err(&pdev->dev, "can't get i2c adapter %d\n", 76288fc39d7SJean Delvare setup->i2c_bus); 76388fc39d7SJean Delvare goto err_driver; 76488fc39d7SJean Delvare } 76588fc39d7SJean Delvare 76688fc39d7SJean Delvare client = i2c_new_device(adapter, &info); 76788fc39d7SJean Delvare i2c_put_adapter(adapter); 76888fc39d7SJean Delvare if (!client) { 76988fc39d7SJean Delvare dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", 77088fc39d7SJean Delvare (unsigned int)info.addr); 77188fc39d7SJean Delvare goto err_driver; 77288fc39d7SJean Delvare } 77388fc39d7SJean Delvare 77488fc39d7SJean Delvare return 0; 77588fc39d7SJean Delvare 77688fc39d7SJean Delvare err_driver: 77788fc39d7SJean Delvare i2c_del_driver(&uda1380_i2c_driver); 77888fc39d7SJean Delvare return -ENODEV; 77988fc39d7SJean Delvare } 780b7482f52SPhilipp Zabel #endif 781b7482f52SPhilipp Zabel 782b7482f52SPhilipp Zabel static int uda1380_probe(struct platform_device *pdev) 783b7482f52SPhilipp Zabel { 784b7482f52SPhilipp Zabel struct snd_soc_device *socdev = platform_get_drvdata(pdev); 785b7482f52SPhilipp Zabel struct uda1380_setup_data *setup; 786b7482f52SPhilipp Zabel struct snd_soc_codec *codec; 787b7c9d852SMark Brown int ret; 788b7482f52SPhilipp Zabel 789b7482f52SPhilipp Zabel pr_info("UDA1380 Audio Codec %s", UDA1380_VERSION); 790b7482f52SPhilipp Zabel 791b7482f52SPhilipp Zabel setup = socdev->codec_data; 792b7482f52SPhilipp Zabel codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 793b7482f52SPhilipp Zabel if (codec == NULL) 794b7482f52SPhilipp Zabel return -ENOMEM; 795b7482f52SPhilipp Zabel 796b7482f52SPhilipp Zabel socdev->codec = codec; 797b7482f52SPhilipp Zabel mutex_init(&codec->mutex); 798b7482f52SPhilipp Zabel INIT_LIST_HEAD(&codec->dapm_widgets); 799b7482f52SPhilipp Zabel INIT_LIST_HEAD(&codec->dapm_paths); 800b7482f52SPhilipp Zabel 801b7482f52SPhilipp Zabel uda1380_socdev = socdev; 802b7c9d852SMark Brown ret = -ENODEV; 803b7c9d852SMark Brown 804b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 805b7482f52SPhilipp Zabel if (setup->i2c_address) { 806b7482f52SPhilipp Zabel codec->hw_write = (hw_write_t)i2c_master_send; 80788fc39d7SJean Delvare ret = uda1380_add_i2c_device(pdev, setup); 808b7482f52SPhilipp Zabel } 809b7482f52SPhilipp Zabel #endif 8103051e41aSJean Delvare 8113051e41aSJean Delvare if (ret != 0) 8123051e41aSJean Delvare kfree(codec); 813b7482f52SPhilipp Zabel return ret; 814b7482f52SPhilipp Zabel } 815b7482f52SPhilipp Zabel 816b7482f52SPhilipp Zabel /* power down chip */ 817b7482f52SPhilipp Zabel static int uda1380_remove(struct platform_device *pdev) 818b7482f52SPhilipp Zabel { 819b7482f52SPhilipp Zabel struct snd_soc_device *socdev = platform_get_drvdata(pdev); 820b7482f52SPhilipp Zabel struct snd_soc_codec *codec = socdev->codec; 821b7482f52SPhilipp Zabel 822b7482f52SPhilipp Zabel if (codec->control_data) 823b7482f52SPhilipp Zabel uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); 824b7482f52SPhilipp Zabel 825b7482f52SPhilipp Zabel snd_soc_free_pcms(socdev); 826b7482f52SPhilipp Zabel snd_soc_dapm_free(socdev); 827b7482f52SPhilipp Zabel #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 82888fc39d7SJean Delvare i2c_unregister_device(codec->control_data); 829b7482f52SPhilipp Zabel i2c_del_driver(&uda1380_i2c_driver); 830b7482f52SPhilipp Zabel #endif 831b7482f52SPhilipp Zabel kfree(codec); 832b7482f52SPhilipp Zabel 833b7482f52SPhilipp Zabel return 0; 834b7482f52SPhilipp Zabel } 835b7482f52SPhilipp Zabel 836b7482f52SPhilipp Zabel struct snd_soc_codec_device soc_codec_dev_uda1380 = { 837b7482f52SPhilipp Zabel .probe = uda1380_probe, 838b7482f52SPhilipp Zabel .remove = uda1380_remove, 839b7482f52SPhilipp Zabel .suspend = uda1380_suspend, 840b7482f52SPhilipp Zabel .resume = uda1380_resume, 841b7482f52SPhilipp Zabel }; 842b7482f52SPhilipp Zabel EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 843b7482f52SPhilipp Zabel 844*64089b84SMark Brown static int __devinit uda1380_modinit(void) 845*64089b84SMark Brown { 846*64089b84SMark Brown return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 847*64089b84SMark Brown } 848*64089b84SMark Brown module_init(uda1380_modinit); 849*64089b84SMark Brown 850*64089b84SMark Brown static void __exit uda1380_exit(void) 851*64089b84SMark Brown { 852*64089b84SMark Brown snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 853*64089b84SMark Brown } 854*64089b84SMark Brown module_exit(uda1380_exit); 855*64089b84SMark Brown 856b7482f52SPhilipp Zabel MODULE_AUTHOR("Giorgio Padrin"); 857b7482f52SPhilipp Zabel MODULE_DESCRIPTION("Audio support for codec Philips UDA1380"); 858b7482f52SPhilipp Zabel MODULE_LICENSE("GPL"); 859