···11-/*22- * ALSA SoC codec driver for HDMI audio codecs.33- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/44- * Author: Ricardo Neri <ricardo.neri@ti.com>55- *66- * This program is free software; you can redistribute it and/or77- * modify it under the terms of the GNU General Public License88- * version 2 as published by the Free Software Foundation.99- *1010- * This program is distributed in the hope that it will be useful, but1111- * WITHOUT ANY WARRANTY; without even the implied warranty of1212- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1313- * General Public License for more details.1414- *1515- * You should have received a copy of the GNU General Public License1616- * along with this program; if not, write to the Free Software1717- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA1818- * 02110-1301 USA1919- *2020- */2121-#include <linux/module.h>2222-#include <sound/soc.h>2323-#include <linux/of.h>2424-#include <linux/of_device.h>2525-2626-#define DRV_NAME "hdmi-audio-codec"2727-2828-static const struct snd_soc_dapm_widget hdmi_widgets[] = {2929- SND_SOC_DAPM_INPUT("RX"),3030- SND_SOC_DAPM_OUTPUT("TX"),3131-};3232-3333-static const struct snd_soc_dapm_route hdmi_routes[] = {3434- { "Capture", NULL, "RX" },3535- { "TX", NULL, "Playback" },3636-};3737-3838-static struct snd_soc_dai_driver hdmi_codec_dai = {3939- .name = "hdmi-hifi",4040- .playback = {4141- .stream_name = "Playback",4242- .channels_min = 2,4343- .channels_max = 8,4444- .rates = SNDRV_PCM_RATE_32000 |4545- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |4646- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |4747- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,4848- .formats = SNDRV_PCM_FMTBIT_S16_LE |4949- SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,5050- .sig_bits = 24,5151- },5252- .capture = {5353- .stream_name = "Capture",5454- .channels_min = 2,5555- .channels_max = 2,5656- .rates = SNDRV_PCM_RATE_32000 |5757- SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |5858- SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |5959- SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,6060- .formats = SNDRV_PCM_FMTBIT_S16_LE |6161- SNDRV_PCM_FMTBIT_S24_LE,6262- },6363-6464-};6565-6666-#ifdef CONFIG_OF6767-static const struct of_device_id hdmi_audio_codec_ids[] = {6868- { .compatible = "linux,hdmi-audio", },6969- { }7070-};7171-MODULE_DEVICE_TABLE(of, hdmi_audio_codec_ids);7272-#endif7373-7474-static struct snd_soc_codec_driver hdmi_codec = {7575- .dapm_widgets = hdmi_widgets,7676- .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),7777- .dapm_routes = hdmi_routes,7878- .num_dapm_routes = ARRAY_SIZE(hdmi_routes),7979- .ignore_pmdown_time = true,8080-};8181-8282-static int hdmi_codec_probe(struct platform_device *pdev)8383-{8484- return snd_soc_register_codec(&pdev->dev, &hdmi_codec,8585- &hdmi_codec_dai, 1);8686-}8787-8888-static int hdmi_codec_remove(struct platform_device *pdev)8989-{9090- snd_soc_unregister_codec(&pdev->dev);9191- return 0;9292-}9393-9494-static struct platform_driver hdmi_codec_driver = {9595- .driver = {9696- .name = DRV_NAME,9797- .of_match_table = of_match_ptr(hdmi_audio_codec_ids),9898- },9999-100100- .probe = hdmi_codec_probe,101101- .remove = hdmi_codec_remove,102102-};103103-104104-module_platform_driver(hdmi_codec_driver);105105-106106-MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");107107-MODULE_DESCRIPTION("ASoC generic HDMI codec driver");108108-MODULE_LICENSE("GPL");109109-MODULE_ALIAS("platform:" DRV_NAME);
+202-103
sound/soc/davinci/davinci-mcasp.c
···80808181 /* McASP specific data */8282 int tdm_slots;8383+ u32 tdm_mask[2];8484+ int slot_width;8385 u8 op_mode;8486 u8 num_serializer;8587 u8 *serial_dir;8688 u8 version;8789 u8 bclk_div;8888- u16 bclk_lrclk_ratio;8990 int streams;9091 u32 irq_request[2];9192 int dma_request[2];···557556 mcasp->bclk_div = div;558557 break;559558560560- case 2: /* BCLK/LRCLK ratio */561561- mcasp->bclk_lrclk_ratio = div;559559+ case 2: /*560560+ * BCLK/LRCLK ratio descries how many bit-clock cycles561561+ * fit into one frame. The clock ratio is given for a562562+ * full period of data (for I2S format both left and563563+ * right channels), so it has to be divided by number564564+ * of tdm-slots (for I2S - divided by 2).565565+ * Instead of storing this ratio, we calculate a new566566+ * tdm_slot width by dividing the the ratio by the567567+ * number of configured tdm slots.568568+ */569569+ mcasp->slot_width = div / mcasp->tdm_slots;570570+ if (div % mcasp->tdm_slots)571571+ dev_warn(mcasp->dev,572572+ "%s(): BCLK/LRCLK %d is not divisible by %d tdm slots",573573+ __func__, div, mcasp->tdm_slots);562574 break;563575564576 default:···610596 return 0;611597}612598599599+/* All serializers must have equal number of channels */600600+static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp, int stream,601601+ int serializers)602602+{603603+ struct snd_pcm_hw_constraint_list *cl = &mcasp->chconstr[stream];604604+ unsigned int *list = (unsigned int *) cl->list;605605+ int slots = mcasp->tdm_slots;606606+ int i, count = 0;607607+608608+ if (mcasp->tdm_mask[stream])609609+ slots = hweight32(mcasp->tdm_mask[stream]);610610+611611+ for (i = 2; i <= slots; i++)612612+ list[count++] = i;613613+614614+ for (i = 2; i <= serializers; i++)615615+ list[count++] = i*slots;616616+617617+ cl->count = count;618618+619619+ return 0;620620+}621621+622622+static int davinci_mcasp_set_ch_constraints(struct davinci_mcasp *mcasp)623623+{624624+ int rx_serializers = 0, tx_serializers = 0, ret, i;625625+626626+ for (i = 0; i < mcasp->num_serializer; i++)627627+ if (mcasp->serial_dir[i] == TX_MODE)628628+ tx_serializers++;629629+ else if (mcasp->serial_dir[i] == RX_MODE)630630+ rx_serializers++;631631+632632+ ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_PLAYBACK,633633+ tx_serializers);634634+ if (ret)635635+ return ret;636636+637637+ ret = davinci_mcasp_ch_constraint(mcasp, SNDRV_PCM_STREAM_CAPTURE,638638+ rx_serializers);639639+640640+ return ret;641641+}642642+643643+644644+static int davinci_mcasp_set_tdm_slot(struct snd_soc_dai *dai,645645+ unsigned int tx_mask,646646+ unsigned int rx_mask,647647+ int slots, int slot_width)648648+{649649+ struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai);650650+651651+ dev_dbg(mcasp->dev,652652+ "%s() tx_mask 0x%08x rx_mask 0x%08x slots %d width %d\n",653653+ __func__, tx_mask, rx_mask, slots, slot_width);654654+655655+ if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {656656+ dev_err(mcasp->dev,657657+ "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n",658658+ tx_mask, rx_mask, slots);659659+ return -EINVAL;660660+ }661661+662662+ if (slot_width &&663663+ (slot_width < 8 || slot_width > 32 || slot_width % 4 != 0)) {664664+ dev_err(mcasp->dev, "%s: Unsupported slot_width %d\n",665665+ __func__, slot_width);666666+ return -EINVAL;667667+ }668668+669669+ mcasp->tdm_slots = slots;670670+ mcasp->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = rx_mask;671671+ mcasp->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = tx_mask;672672+ mcasp->slot_width = slot_width;673673+674674+ return davinci_mcasp_set_ch_constraints(mcasp);675675+}676676+613677static int davinci_config_channel_size(struct davinci_mcasp *mcasp,614614- int word_length)678678+ int sample_width)615679{616680 u32 fmt;617617- u32 tx_rotate = (word_length / 4) & 0x7;618618- u32 mask = (1ULL << word_length) - 1;681681+ u32 tx_rotate = (sample_width / 4) & 0x7;682682+ u32 mask = (1ULL << sample_width) - 1;683683+ u32 slot_width = sample_width;684684+619685 /*620686 * For captured data we should not rotate, inversion and masking is621687 * enoguh to get the data to the right position:···708614 u32 rx_rotate = 0;709615710616 /*711711- * if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()712712- * callback, take it into account here. That allows us to for example713713- * send 32 bits per channel to the codec, while only 16 of them carry714714- * audio payload.715715- * The clock ratio is given for a full period of data (for I2S format716716- * both left and right channels), so it has to be divided by number of717717- * tdm-slots (for I2S - divided by 2).617617+ * Setting the tdm slot width either with set_clkdiv() or618618+ * set_tdm_slot() allows us to for example send 32 bits per619619+ * channel to the codec, while only 16 of them carry audio620620+ * payload.718621 */719719- if (mcasp->bclk_lrclk_ratio) {720720- u32 slot_length = mcasp->bclk_lrclk_ratio / mcasp->tdm_slots;721721-622622+ if (mcasp->slot_width) {722623 /*723723- * When we have more bclk then it is needed for the data, we724724- * need to use the rotation to move the received samples to have725725- * correct alignment.624624+ * When we have more bclk then it is needed for the625625+ * data, we need to use the rotation to move the626626+ * received samples to have correct alignment.726627 */727727- rx_rotate = (slot_length - word_length) / 4;728728- word_length = slot_length;628628+ slot_width = mcasp->slot_width;629629+ rx_rotate = (slot_width - sample_width) / 4;729630 }730631731632 /* mapping of the XSSZ bit-field as described in the datasheet */732732- fmt = (word_length >> 1) - 1;633633+ fmt = (slot_width >> 1) - 1;733634734635 if (mcasp->op_mode != DAVINCI_MCASP_DIT_MODE) {735636 mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, RXSSZ(fmt),···865776866777 /*867778 * If more than one serializer is needed, then use them with868868- * their specified tdm_slots count. Otherwise, one serializer869869- * can cope with the transaction using as many slots as channels870870- * in the stream, requires channels symmetry779779+ * all the specified tdm_slots. Otherwise, one serializer can780780+ * cope with the transaction using just as many slots as there781781+ * are channels in the stream.871782 */872872- active_serializers = (channels + total_slots - 1) / total_slots;873873- if (active_serializers == 1)874874- active_slots = channels;875875- else876876- active_slots = total_slots;783783+ if (mcasp->tdm_mask[stream]) {784784+ active_slots = hweight32(mcasp->tdm_mask[stream]);785785+ active_serializers = (channels + active_slots - 1) /786786+ active_slots;787787+ if (active_serializers == 1) {788788+ active_slots = channels;789789+ for (i = 0; i < total_slots; i++) {790790+ if ((1 << i) & mcasp->tdm_mask[stream]) {791791+ mask |= (1 << i);792792+ if (--active_slots <= 0)793793+ break;794794+ }795795+ }796796+ }797797+ } else {798798+ active_serializers = (channels + total_slots - 1) / total_slots;799799+ if (active_serializers == 1)800800+ active_slots = channels;801801+ else802802+ active_slots = total_slots;877803878878- for (i = 0; i < active_slots; i++)879879- mask |= (1 << i);880880-804804+ for (i = 0; i < active_slots; i++)805805+ mask |= (1 << i);806806+ }881807 mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);882808883809 if (!mcasp->dat_port)884810 busel = TXSEL;885811886886- mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);887887- mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);888888- mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,889889- FSXMOD(total_slots), FSXMOD(0x1FF));890890-891891- mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);892892- mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);893893- mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,894894- FSRMOD(total_slots), FSRMOD(0x1FF));812812+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {813813+ mcasp_set_reg(mcasp, DAVINCI_MCASP_TXTDM_REG, mask);814814+ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, busel | TXORD);815815+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG,816816+ FSXMOD(total_slots), FSXMOD(0x1FF));817817+ } else if (stream == SNDRV_PCM_STREAM_CAPTURE) {818818+ mcasp_set_reg(mcasp, DAVINCI_MCASP_RXTDM_REG, mask);819819+ mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, busel | RXORD);820820+ mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG,821821+ FSRMOD(total_slots), FSRMOD(0x1FF));822822+ }895823896824 return 0;897825}···1028922 int sbits = params_width(params);1029923 int ppm, div;1030924925925+ if (mcasp->slot_width)926926+ sbits = mcasp->slot_width;927927+1031928 div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots,1032929 &ppm);1033930 if (ppm)···11361027 struct snd_interval range;11371028 int i;1138102910301030+ if (rd->mcasp->slot_width)10311031+ sbits = rd->mcasp->slot_width;10321032+11391033 snd_interval_any(&range);11401034 range.empty = 1;11411035···1181106911821070 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {11831071 if (snd_mask_test(fmt, i)) {11841184- uint bclk_freq = snd_pcm_format_width(i)*slots*rate;10721072+ uint sbits = snd_pcm_format_width(i);11851073 int ppm;1186107411871187- davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm);10751075+ if (rd->mcasp->slot_width)10761076+ sbits = rd->mcasp->slot_width;10771077+10781078+ davinci_mcasp_calc_clk_div(rd->mcasp, sbits*slots*rate,10791079+ &ppm);11881080 if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) {11891081 snd_mask_set(&nfmt, i);11901082 count++;···12101094 &mcasp->ruledata[substream->stream];12111095 u32 max_channels = 0;12121096 int i, dir;10971097+ int tdm_slots = mcasp->tdm_slots;10981098+10991099+ if (mcasp->tdm_mask[substream->stream])11001100+ tdm_slots = hweight32(mcasp->tdm_mask[substream->stream]);1213110112141102 mcasp->substreams[substream->stream] = substream;12151103···12341114 max_channels++;12351115 }12361116 ruledata->serializers = max_channels;12371237- max_channels *= mcasp->tdm_slots;11171117+ max_channels *= tdm_slots;12381118 /*12391119 * If the already active stream has less channels than the calculated12401120 * limnit based on the seirializers * tdm_slots, we need to use that as···12441124 */12451125 if (mcasp->channels && mcasp->channels < max_channels)12461126 max_channels = mcasp->channels;11271127+ /*11281128+ * But we can always allow channels upto the amount of11291129+ * the available tdm_slots.11301130+ */11311131+ if (max_channels < tdm_slots)11321132+ max_channels = tdm_slots;1247113312481134 snd_pcm_hw_constraint_minmax(substream->runtime,12491135 SNDRV_PCM_HW_PARAM_CHANNELS,12501136 2, max_channels);1251113712521252- if (mcasp->chconstr[substream->stream].count)12531253- snd_pcm_hw_constraint_list(substream->runtime,12541254- 0, SNDRV_PCM_HW_PARAM_CHANNELS,12551255- &mcasp->chconstr[substream->stream]);11381138+ snd_pcm_hw_constraint_list(substream->runtime,11391139+ 0, SNDRV_PCM_HW_PARAM_CHANNELS,11401140+ &mcasp->chconstr[substream->stream]);11411141+11421142+ if (mcasp->slot_width)11431143+ snd_pcm_hw_constraint_minmax(substream->runtime,11441144+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,11451145+ 8, mcasp->slot_width);1256114612571147 /*12581148 * If we rely on implicit BCLK divider setting we should···13141184 .set_fmt = davinci_mcasp_set_dai_fmt,13151185 .set_clkdiv = davinci_mcasp_set_clkdiv,13161186 .set_sysclk = davinci_mcasp_set_sysclk,11871187+ .set_tdm_slot = davinci_mcasp_set_tdm_slot,13171188};1318118913191190static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai)···16451514 return pdata;16461515}1647151616481648-/* All serializers must have equal number of channels */16491649-static int davinci_mcasp_ch_constraint(struct davinci_mcasp *mcasp,16501650- struct snd_pcm_hw_constraint_list *cl,16511651- int serializers)16521652-{16531653- unsigned int *list;16541654- int i, count = 0;16551655-16561656- if (serializers <= 1)16571657- return 0;16581658-16591659- list = devm_kzalloc(mcasp->dev, sizeof(unsigned int) *16601660- (mcasp->tdm_slots + serializers - 2),16611661- GFP_KERNEL);16621662- if (!list)16631663- return -ENOMEM;16641664-16651665- for (i = 2; i <= mcasp->tdm_slots; i++)16661666- list[count++] = i;16671667-16681668- for (i = 2; i <= serializers; i++)16691669- list[count++] = i*mcasp->tdm_slots;16701670-16711671- cl->count = count;16721672- cl->list = list;16731673-16741674- return 0;16751675-}16761676-16771677-16781678-static int davinci_mcasp_init_ch_constraints(struct davinci_mcasp *mcasp)16791679-{16801680- int rx_serializers = 0, tx_serializers = 0, ret, i;16811681-16821682- for (i = 0; i < mcasp->num_serializer; i++)16831683- if (mcasp->serial_dir[i] == TX_MODE)16841684- tx_serializers++;16851685- else if (mcasp->serial_dir[i] == RX_MODE)16861686- rx_serializers++;16871687-16881688- ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[16891689- SNDRV_PCM_STREAM_PLAYBACK],16901690- tx_serializers);16911691- if (ret)16921692- return ret;16931693-16941694- ret = davinci_mcasp_ch_constraint(mcasp, &mcasp->chconstr[16951695- SNDRV_PCM_STREAM_CAPTURE],16961696- rx_serializers);16971697-16981698- return ret;16991699-}17001700-17011517enum {17021518 PCM_EDMA,17031519 PCM_SDMA,···18611783 mcasp->fifo_base = DAVINCI_MCASP_V3_AFIFO_BASE;18621784 }1863178518641864- ret = davinci_mcasp_init_ch_constraints(mcasp);17861786+ /* Allocate memory for long enough list for all possible17871787+ * scenarios. Maximum number tdm slots is 32 and there cannot17881788+ * be more serializers than given in the configuration. The17891789+ * serializer directions could be taken into account, but it17901790+ * would make code much more complex and save only couple of17911791+ * bytes.17921792+ */17931793+ mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list =17941794+ devm_kzalloc(mcasp->dev, sizeof(unsigned int) *17951795+ (32 + mcasp->num_serializer - 2),17961796+ GFP_KERNEL);17971797+17981798+ mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list =17991799+ devm_kzalloc(mcasp->dev, sizeof(unsigned int) *18001800+ (32 + mcasp->num_serializer - 2),18011801+ GFP_KERNEL);18021802+18031803+ if (!mcasp->chconstr[SNDRV_PCM_STREAM_PLAYBACK].list ||18041804+ !mcasp->chconstr[SNDRV_PCM_STREAM_CAPTURE].list)18051805+ return -ENOMEM;18061806+18071807+ ret = davinci_mcasp_set_ch_constraints(mcasp);18651808 if (ret)18661809 goto err;18671810