adv7511_audio.c (6314B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Analog Devices ADV7511 HDMI transmitter driver 4 * 5 * Copyright 2012 Analog Devices Inc. 6 * Copyright (c) 2016, Linaro Limited 7 */ 8 9#include <sound/core.h> 10#include <sound/hdmi-codec.h> 11#include <sound/pcm.h> 12#include <sound/soc.h> 13#include <linux/of_graph.h> 14 15#include "adv7511.h" 16 17static void adv7511_calc_cts_n(unsigned int f_tmds, unsigned int fs, 18 unsigned int *cts, unsigned int *n) 19{ 20 switch (fs) { 21 case 32000: 22 case 48000: 23 case 96000: 24 case 192000: 25 *n = fs * 128 / 1000; 26 break; 27 case 44100: 28 case 88200: 29 case 176400: 30 *n = fs * 128 / 900; 31 break; 32 } 33 34 *cts = ((f_tmds * *n) / (128 * fs)) * 1000; 35} 36 37static int adv7511_update_cts_n(struct adv7511 *adv7511) 38{ 39 unsigned int cts = 0; 40 unsigned int n = 0; 41 42 adv7511_calc_cts_n(adv7511->f_tmds, adv7511->f_audio, &cts, &n); 43 44 regmap_write(adv7511->regmap, ADV7511_REG_N0, (n >> 16) & 0xf); 45 regmap_write(adv7511->regmap, ADV7511_REG_N1, (n >> 8) & 0xff); 46 regmap_write(adv7511->regmap, ADV7511_REG_N2, n & 0xff); 47 48 regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL0, 49 (cts >> 16) & 0xf); 50 regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL1, 51 (cts >> 8) & 0xff); 52 regmap_write(adv7511->regmap, ADV7511_REG_CTS_MANUAL2, 53 cts & 0xff); 54 55 return 0; 56} 57 58static int adv7511_hdmi_hw_params(struct device *dev, void *data, 59 struct hdmi_codec_daifmt *fmt, 60 struct hdmi_codec_params *hparms) 61{ 62 struct adv7511 *adv7511 = dev_get_drvdata(dev); 63 unsigned int audio_source, i2s_format = 0; 64 unsigned int invert_clock; 65 unsigned int rate; 66 unsigned int len; 67 68 switch (hparms->sample_rate) { 69 case 32000: 70 rate = ADV7511_SAMPLE_FREQ_32000; 71 break; 72 case 44100: 73 rate = ADV7511_SAMPLE_FREQ_44100; 74 break; 75 case 48000: 76 rate = ADV7511_SAMPLE_FREQ_48000; 77 break; 78 case 88200: 79 rate = ADV7511_SAMPLE_FREQ_88200; 80 break; 81 case 96000: 82 rate = ADV7511_SAMPLE_FREQ_96000; 83 break; 84 case 176400: 85 rate = ADV7511_SAMPLE_FREQ_176400; 86 break; 87 case 192000: 88 rate = ADV7511_SAMPLE_FREQ_192000; 89 break; 90 default: 91 return -EINVAL; 92 } 93 94 switch (hparms->sample_width) { 95 case 16: 96 len = ADV7511_I2S_SAMPLE_LEN_16; 97 break; 98 case 18: 99 len = ADV7511_I2S_SAMPLE_LEN_18; 100 break; 101 case 20: 102 len = ADV7511_I2S_SAMPLE_LEN_20; 103 break; 104 case 32: 105 if (fmt->bit_fmt != SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE) 106 return -EINVAL; 107 fallthrough; 108 case 24: 109 len = ADV7511_I2S_SAMPLE_LEN_24; 110 break; 111 default: 112 return -EINVAL; 113 } 114 115 switch (fmt->fmt) { 116 case HDMI_I2S: 117 audio_source = ADV7511_AUDIO_SOURCE_I2S; 118 i2s_format = ADV7511_I2S_FORMAT_I2S; 119 if (fmt->bit_fmt == SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE) 120 i2s_format = ADV7511_I2S_IEC958_DIRECT; 121 break; 122 case HDMI_RIGHT_J: 123 audio_source = ADV7511_AUDIO_SOURCE_I2S; 124 i2s_format = ADV7511_I2S_FORMAT_RIGHT_J; 125 break; 126 case HDMI_LEFT_J: 127 audio_source = ADV7511_AUDIO_SOURCE_I2S; 128 i2s_format = ADV7511_I2S_FORMAT_LEFT_J; 129 break; 130 case HDMI_SPDIF: 131 audio_source = ADV7511_AUDIO_SOURCE_SPDIF; 132 break; 133 default: 134 return -EINVAL; 135 } 136 137 invert_clock = fmt->bit_clk_inv; 138 139 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_SOURCE, 0x70, 140 audio_source << 4); 141 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, BIT(6), 142 invert_clock << 6); 143 regmap_update_bits(adv7511->regmap, ADV7511_REG_I2S_CONFIG, 0x03, 144 i2s_format); 145 146 adv7511->audio_source = audio_source; 147 148 adv7511->f_audio = hparms->sample_rate; 149 150 adv7511_update_cts_n(adv7511); 151 152 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CFG3, 153 ADV7511_AUDIO_CFG3_LEN_MASK, len); 154 regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG, 155 ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4); 156 regmap_write(adv7511->regmap, 0x73, 0x1); 157 158 return 0; 159} 160 161static int audio_startup(struct device *dev, void *data) 162{ 163 struct adv7511 *adv7511 = dev_get_drvdata(dev); 164 165 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, 166 BIT(7), 0); 167 168 /* hide Audio infoframe updates */ 169 regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE, 170 BIT(5), BIT(5)); 171 /* enable N/CTS, enable Audio sample packets */ 172 regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, 173 BIT(5), BIT(5)); 174 /* enable N/CTS */ 175 regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, 176 BIT(6), BIT(6)); 177 /* not copyrighted */ 178 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CFG1, 179 BIT(5), BIT(5)); 180 /* enable audio infoframes */ 181 regmap_update_bits(adv7511->regmap, ADV7511_REG_PACKET_ENABLE1, 182 BIT(3), BIT(3)); 183 /* AV mute disable */ 184 regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0), 185 BIT(7) | BIT(6), BIT(7)); 186 /* use Audio infoframe updated info */ 187 regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1), 188 BIT(5), 0); 189 /* enable SPDIF receiver */ 190 if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) 191 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, 192 BIT(7), BIT(7)); 193 194 return 0; 195} 196 197static void audio_shutdown(struct device *dev, void *data) 198{ 199 struct adv7511 *adv7511 = dev_get_drvdata(dev); 200 201 if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF) 202 regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG, 203 BIT(7), 0); 204} 205 206static int adv7511_hdmi_i2s_get_dai_id(struct snd_soc_component *component, 207 struct device_node *endpoint) 208{ 209 struct of_endpoint of_ep; 210 int ret; 211 212 ret = of_graph_parse_endpoint(endpoint, &of_ep); 213 if (ret < 0) 214 return ret; 215 216 /* 217 * HDMI sound should be located as reg = <2> 218 * Then, it is sound port 0 219 */ 220 if (of_ep.port == 2) 221 return 0; 222 223 return -EINVAL; 224} 225 226static const struct hdmi_codec_ops adv7511_codec_ops = { 227 .hw_params = adv7511_hdmi_hw_params, 228 .audio_shutdown = audio_shutdown, 229 .audio_startup = audio_startup, 230 .get_dai_id = adv7511_hdmi_i2s_get_dai_id, 231}; 232 233static const struct hdmi_codec_pdata codec_data = { 234 .ops = &adv7511_codec_ops, 235 .max_i2s_channels = 2, 236 .i2s = 1, 237 .spdif = 1, 238}; 239 240int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511) 241{ 242 adv7511->audio_pdev = platform_device_register_data(dev, 243 HDMI_CODEC_DRV_NAME, 244 PLATFORM_DEVID_AUTO, 245 &codec_data, 246 sizeof(codec_data)); 247 return PTR_ERR_OR_ZERO(adv7511->audio_pdev); 248} 249 250void adv7511_audio_exit(struct adv7511 *adv7511) 251{ 252 if (adv7511->audio_pdev) { 253 platform_device_unregister(adv7511->audio_pdev); 254 adv7511->audio_pdev = NULL; 255 } 256}