cygnus-ssp.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. /*
  2. * Copyright (C) 2014-2015 Broadcom Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation version 2.
  7. *
  8. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  9. * kind, whether express or implied; without even the implied warranty
  10. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/clk.h>
  14. #include <linux/delay.h>
  15. #include <linux/init.h>
  16. #include <linux/io.h>
  17. #include <linux/module.h>
  18. #include <linux/of_device.h>
  19. #include <linux/slab.h>
  20. #include <sound/core.h>
  21. #include <sound/pcm.h>
  22. #include <sound/pcm_params.h>
  23. #include <sound/soc.h>
  24. #include <sound/soc-dai.h>
  25. #include "cygnus-ssp.h"
  26. #define DEFAULT_VCO 1354750204
  27. #define CAPTURE_FCI_ID_BASE 0x180
  28. #define CYGNUS_SSP_TRISTATE_MASK 0x001fff
  29. #define CYGNUS_PLLCLKSEL_MASK 0xf
  30. /* Used with stream_on field to indicate which streams are active */
  31. #define PLAYBACK_STREAM_MASK BIT(0)
  32. #define CAPTURE_STREAM_MASK BIT(1)
  33. #define I2S_STREAM_CFG_MASK 0xff003ff
  34. #define I2S_CAP_STREAM_CFG_MASK 0xf0
  35. #define SPDIF_STREAM_CFG_MASK 0x3ff
  36. #define CH_GRP_STEREO 0x1
  37. /* Begin register offset defines */
  38. #define AUD_MISC_SEROUT_OE_REG_BASE 0x01c
  39. #define AUD_MISC_SEROUT_SPDIF_OE 12
  40. #define AUD_MISC_SEROUT_MCLK_OE 3
  41. #define AUD_MISC_SEROUT_LRCK_OE 2
  42. #define AUD_MISC_SEROUT_SCLK_OE 1
  43. #define AUD_MISC_SEROUT_SDAT_OE 0
  44. /* AUD_FMM_BF_CTRL_xxx regs */
  45. #define BF_DST_CFG0_OFFSET 0x100
  46. #define BF_DST_CFG1_OFFSET 0x104
  47. #define BF_DST_CFG2_OFFSET 0x108
  48. #define BF_DST_CTRL0_OFFSET 0x130
  49. #define BF_DST_CTRL1_OFFSET 0x134
  50. #define BF_DST_CTRL2_OFFSET 0x138
  51. #define BF_SRC_CFG0_OFFSET 0x148
  52. #define BF_SRC_CFG1_OFFSET 0x14c
  53. #define BF_SRC_CFG2_OFFSET 0x150
  54. #define BF_SRC_CFG3_OFFSET 0x154
  55. #define BF_SRC_CTRL0_OFFSET 0x1c0
  56. #define BF_SRC_CTRL1_OFFSET 0x1c4
  57. #define BF_SRC_CTRL2_OFFSET 0x1c8
  58. #define BF_SRC_CTRL3_OFFSET 0x1cc
  59. #define BF_SRC_GRP0_OFFSET 0x1fc
  60. #define BF_SRC_GRP1_OFFSET 0x200
  61. #define BF_SRC_GRP2_OFFSET 0x204
  62. #define BF_SRC_GRP3_OFFSET 0x208
  63. #define BF_SRC_GRP_EN_OFFSET 0x320
  64. #define BF_SRC_GRP_FLOWON_OFFSET 0x324
  65. #define BF_SRC_GRP_SYNC_DIS_OFFSET 0x328
  66. /* AUD_FMM_IOP_OUT_I2S_xxx regs */
  67. #define OUT_I2S_0_STREAM_CFG_OFFSET 0xa00
  68. #define OUT_I2S_0_CFG_OFFSET 0xa04
  69. #define OUT_I2S_0_MCLK_CFG_OFFSET 0xa0c
  70. #define OUT_I2S_1_STREAM_CFG_OFFSET 0xa40
  71. #define OUT_I2S_1_CFG_OFFSET 0xa44
  72. #define OUT_I2S_1_MCLK_CFG_OFFSET 0xa4c
  73. #define OUT_I2S_2_STREAM_CFG_OFFSET 0xa80
  74. #define OUT_I2S_2_CFG_OFFSET 0xa84
  75. #define OUT_I2S_2_MCLK_CFG_OFFSET 0xa8c
  76. /* AUD_FMM_IOP_OUT_SPDIF_xxx regs */
  77. #define SPDIF_STREAM_CFG_OFFSET 0xac0
  78. #define SPDIF_CTRL_OFFSET 0xac4
  79. #define SPDIF_FORMAT_CFG_OFFSET 0xad8
  80. #define SPDIF_MCLK_CFG_OFFSET 0xadc
  81. /* AUD_FMM_IOP_PLL_0_xxx regs */
  82. #define IOP_PLL_0_MACRO_OFFSET 0xb00
  83. #define IOP_PLL_0_MDIV_Ch0_OFFSET 0xb14
  84. #define IOP_PLL_0_MDIV_Ch1_OFFSET 0xb18
  85. #define IOP_PLL_0_MDIV_Ch2_OFFSET 0xb1c
  86. #define IOP_PLL_0_ACTIVE_MDIV_Ch0_OFFSET 0xb30
  87. #define IOP_PLL_0_ACTIVE_MDIV_Ch1_OFFSET 0xb34
  88. #define IOP_PLL_0_ACTIVE_MDIV_Ch2_OFFSET 0xb38
  89. /* AUD_FMM_IOP_xxx regs */
  90. #define IOP_PLL_0_CONTROL_OFFSET 0xb04
  91. #define IOP_PLL_0_USER_NDIV_OFFSET 0xb08
  92. #define IOP_PLL_0_ACTIVE_NDIV_OFFSET 0xb20
  93. #define IOP_PLL_0_RESET_OFFSET 0xb5c
  94. /* AUD_FMM_IOP_IN_I2S_xxx regs */
  95. #define IN_I2S_0_STREAM_CFG_OFFSET 0x00
  96. #define IN_I2S_0_CFG_OFFSET 0x04
  97. #define IN_I2S_1_STREAM_CFG_OFFSET 0x40
  98. #define IN_I2S_1_CFG_OFFSET 0x44
  99. #define IN_I2S_2_STREAM_CFG_OFFSET 0x80
  100. #define IN_I2S_2_CFG_OFFSET 0x84
  101. /* AUD_FMM_IOP_MISC_xxx regs */
  102. #define IOP_SW_INIT_LOGIC 0x1c0
  103. /* End register offset defines */
  104. /* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_0_REG */
  105. #define I2S_OUT_MCLKRATE_SHIFT 16
  106. /* AUD_FMM_IOP_OUT_I2S_x_MCLK_CFG_REG */
  107. #define I2S_OUT_PLLCLKSEL_SHIFT 0
  108. /* AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG */
  109. #define I2S_OUT_STREAM_ENA 31
  110. #define I2S_OUT_STREAM_CFG_GROUP_ID 20
  111. #define I2S_OUT_STREAM_CFG_CHANNEL_GROUPING 24
  112. /* AUD_FMM_IOP_IN_I2S_x_CAP */
  113. #define I2S_IN_STREAM_CFG_CAP_ENA 31
  114. #define I2S_IN_STREAM_CFG_0_GROUP_ID 4
  115. /* AUD_FMM_IOP_OUT_I2S_x_I2S_CFG_REG */
  116. #define I2S_OUT_CFGX_CLK_ENA 0
  117. #define I2S_OUT_CFGX_DATA_ENABLE 1
  118. #define I2S_OUT_CFGX_DATA_ALIGNMENT 6
  119. #define I2S_OUT_CFGX_BITS_PER_SLOT 13
  120. #define I2S_OUT_CFGX_VALID_SLOT 14
  121. #define I2S_OUT_CFGX_FSYNC_WIDTH 18
  122. #define I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32 26
  123. #define I2S_OUT_CFGX_SLAVE_MODE 30
  124. #define I2S_OUT_CFGX_TDM_MODE 31
  125. /* AUD_FMM_BF_CTRL_SOURCECH_CFGx_REG */
  126. #define BF_SRC_CFGX_SFIFO_ENA 0
  127. #define BF_SRC_CFGX_BUFFER_PAIR_ENABLE 1
  128. #define BF_SRC_CFGX_SAMPLE_CH_MODE 2
  129. #define BF_SRC_CFGX_SFIFO_SZ_DOUBLE 5
  130. #define BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY 10
  131. #define BF_SRC_CFGX_BIT_RES 20
  132. #define BF_SRC_CFGX_PROCESS_SEQ_ID_VALID 31
  133. /* AUD_FMM_BF_CTRL_DESTCH_CFGx_REG */
  134. #define BF_DST_CFGX_CAP_ENA 0
  135. #define BF_DST_CFGX_BUFFER_PAIR_ENABLE 1
  136. #define BF_DST_CFGX_DFIFO_SZ_DOUBLE 2
  137. #define BF_DST_CFGX_NOT_PAUSE_WHEN_FULL 11
  138. #define BF_DST_CFGX_FCI_ID 12
  139. #define BF_DST_CFGX_CAP_MODE 24
  140. #define BF_DST_CFGX_PROC_SEQ_ID_VALID 31
  141. /* AUD_FMM_IOP_OUT_SPDIF_xxx */
  142. #define SPDIF_0_OUT_DITHER_ENA 3
  143. #define SPDIF_0_OUT_STREAM_ENA 31
  144. /* AUD_FMM_IOP_PLL_0_USER */
  145. #define IOP_PLL_0_USER_NDIV_FRAC 10
  146. /* AUD_FMM_IOP_PLL_0_ACTIVE */
  147. #define IOP_PLL_0_ACTIVE_NDIV_FRAC 10
  148. #define INIT_SSP_REGS(num) (struct cygnus_ssp_regs){ \
  149. .i2s_stream_cfg = OUT_I2S_ ##num## _STREAM_CFG_OFFSET, \
  150. .i2s_cap_stream_cfg = IN_I2S_ ##num## _STREAM_CFG_OFFSET, \
  151. .i2s_cfg = OUT_I2S_ ##num## _CFG_OFFSET, \
  152. .i2s_cap_cfg = IN_I2S_ ##num## _CFG_OFFSET, \
  153. .i2s_mclk_cfg = OUT_I2S_ ##num## _MCLK_CFG_OFFSET, \
  154. .bf_destch_ctrl = BF_DST_CTRL ##num## _OFFSET, \
  155. .bf_destch_cfg = BF_DST_CFG ##num## _OFFSET, \
  156. .bf_sourcech_ctrl = BF_SRC_CTRL ##num## _OFFSET, \
  157. .bf_sourcech_cfg = BF_SRC_CFG ##num## _OFFSET, \
  158. .bf_sourcech_grp = BF_SRC_GRP ##num## _OFFSET \
  159. }
  160. struct pll_macro_entry {
  161. u32 mclk;
  162. u32 pll_ch_num;
  163. };
  164. /*
  165. * PLL has 3 output channels (1x, 2x, and 4x). Below are
  166. * the common MCLK frequencies used by audio driver
  167. */
  168. static const struct pll_macro_entry pll_predef_mclk[] = {
  169. { 4096000, 0},
  170. { 8192000, 1},
  171. {16384000, 2},
  172. { 5644800, 0},
  173. {11289600, 1},
  174. {22579200, 2},
  175. { 6144000, 0},
  176. {12288000, 1},
  177. {24576000, 2},
  178. {12288000, 0},
  179. {24576000, 1},
  180. {49152000, 2},
  181. {22579200, 0},
  182. {45158400, 1},
  183. {90316800, 2},
  184. {24576000, 0},
  185. {49152000, 1},
  186. {98304000, 2},
  187. };
  188. #define CYGNUS_RATE_MIN 8000
  189. #define CYGNUS_RATE_MAX 384000
  190. /* List of valid frame sizes for tdm mode */
  191. static const int ssp_valid_tdm_framesize[] = {32, 64, 128, 256, 512};
  192. static const unsigned int cygnus_rates[] = {
  193. 8000, 11025, 16000, 22050, 32000, 44100, 48000,
  194. 88200, 96000, 176400, 192000, 352800, 384000
  195. };
  196. static const struct snd_pcm_hw_constraint_list cygnus_rate_constraint = {
  197. .count = ARRAY_SIZE(cygnus_rates),
  198. .list = cygnus_rates,
  199. };
  200. static struct cygnus_aio_port *cygnus_dai_get_portinfo(struct snd_soc_dai *dai)
  201. {
  202. struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
  203. return &cygaud->portinfo[dai->id];
  204. }
  205. static int audio_ssp_init_portregs(struct cygnus_aio_port *aio)
  206. {
  207. u32 value, fci_id;
  208. int status = 0;
  209. switch (aio->port_type) {
  210. case PORT_TDM:
  211. value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  212. value &= ~I2S_STREAM_CFG_MASK;
  213. /* Set Group ID */
  214. writel(aio->portnum,
  215. aio->cygaud->audio + aio->regs.bf_sourcech_grp);
  216. /* Configure the AUD_FMM_IOP_OUT_I2S_x_STREAM_CFG reg */
  217. value |= aio->portnum << I2S_OUT_STREAM_CFG_GROUP_ID;
  218. value |= aio->portnum; /* FCI ID is the port num */
  219. value |= CH_GRP_STEREO << I2S_OUT_STREAM_CFG_CHANNEL_GROUPING;
  220. writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  221. /* Configure the AUD_FMM_BF_CTRL_SOURCECH_CFGX reg */
  222. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  223. value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
  224. value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
  225. value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
  226. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  227. /* Configure the AUD_FMM_IOP_IN_I2S_x_CAP_STREAM_CFG_0 reg */
  228. value = readl(aio->cygaud->i2s_in +
  229. aio->regs.i2s_cap_stream_cfg);
  230. value &= ~I2S_CAP_STREAM_CFG_MASK;
  231. value |= aio->portnum << I2S_IN_STREAM_CFG_0_GROUP_ID;
  232. writel(value, aio->cygaud->i2s_in +
  233. aio->regs.i2s_cap_stream_cfg);
  234. /* Configure the AUD_FMM_BF_CTRL_DESTCH_CFGX_REG_BASE reg */
  235. fci_id = CAPTURE_FCI_ID_BASE + aio->portnum;
  236. value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
  237. value |= BIT(BF_DST_CFGX_DFIFO_SZ_DOUBLE);
  238. value &= ~BIT(BF_DST_CFGX_NOT_PAUSE_WHEN_FULL);
  239. value |= (fci_id << BF_DST_CFGX_FCI_ID);
  240. value |= BIT(BF_DST_CFGX_PROC_SEQ_ID_VALID);
  241. writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
  242. /* Enable the transmit pin for this port */
  243. value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  244. value &= ~BIT((aio->portnum * 4) + AUD_MISC_SEROUT_SDAT_OE);
  245. writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  246. break;
  247. case PORT_SPDIF:
  248. writel(aio->portnum, aio->cygaud->audio + BF_SRC_GRP3_OFFSET);
  249. value = readl(aio->cygaud->audio + SPDIF_CTRL_OFFSET);
  250. value |= BIT(SPDIF_0_OUT_DITHER_ENA);
  251. writel(value, aio->cygaud->audio + SPDIF_CTRL_OFFSET);
  252. /* Enable and set the FCI ID for the SPDIF channel */
  253. value = readl(aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
  254. value &= ~SPDIF_STREAM_CFG_MASK;
  255. value |= aio->portnum; /* FCI ID is the port num */
  256. value |= BIT(SPDIF_0_OUT_STREAM_ENA);
  257. writel(value, aio->cygaud->audio + SPDIF_STREAM_CFG_OFFSET);
  258. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  259. value &= ~BIT(BF_SRC_CFGX_NOT_PAUSE_WHEN_EMPTY);
  260. value |= BIT(BF_SRC_CFGX_SFIFO_SZ_DOUBLE);
  261. value |= BIT(BF_SRC_CFGX_PROCESS_SEQ_ID_VALID);
  262. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  263. /* Enable the spdif output pin */
  264. value = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  265. value &= ~BIT(AUD_MISC_SEROUT_SPDIF_OE);
  266. writel(value, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  267. break;
  268. default:
  269. dev_err(aio->cygaud->dev, "Port not supported\n");
  270. status = -EINVAL;
  271. }
  272. return status;
  273. }
  274. static void audio_ssp_in_enable(struct cygnus_aio_port *aio)
  275. {
  276. u32 value;
  277. value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
  278. value |= BIT(BF_DST_CFGX_CAP_ENA);
  279. writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
  280. writel(0x1, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
  281. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  282. value |= BIT(I2S_OUT_CFGX_CLK_ENA);
  283. value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
  284. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  285. value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
  286. value |= BIT(I2S_IN_STREAM_CFG_CAP_ENA);
  287. writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
  288. aio->streams_on |= CAPTURE_STREAM_MASK;
  289. }
  290. static void audio_ssp_in_disable(struct cygnus_aio_port *aio)
  291. {
  292. u32 value;
  293. value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
  294. value &= ~BIT(I2S_IN_STREAM_CFG_CAP_ENA);
  295. writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_stream_cfg);
  296. aio->streams_on &= ~CAPTURE_STREAM_MASK;
  297. /* If both playback and capture are off */
  298. if (!aio->streams_on) {
  299. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  300. value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
  301. value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
  302. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  303. }
  304. writel(0x0, aio->cygaud->audio + aio->regs.bf_destch_ctrl);
  305. value = readl(aio->cygaud->audio + aio->regs.bf_destch_cfg);
  306. value &= ~BIT(BF_DST_CFGX_CAP_ENA);
  307. writel(value, aio->cygaud->audio + aio->regs.bf_destch_cfg);
  308. }
  309. static int audio_ssp_out_enable(struct cygnus_aio_port *aio)
  310. {
  311. u32 value;
  312. int status = 0;
  313. switch (aio->port_type) {
  314. case PORT_TDM:
  315. value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  316. value |= BIT(I2S_OUT_STREAM_ENA);
  317. writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  318. writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
  319. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  320. value |= BIT(I2S_OUT_CFGX_CLK_ENA);
  321. value |= BIT(I2S_OUT_CFGX_DATA_ENABLE);
  322. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  323. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  324. value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
  325. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  326. aio->streams_on |= PLAYBACK_STREAM_MASK;
  327. break;
  328. case PORT_SPDIF:
  329. value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
  330. value |= 0x3;
  331. writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
  332. writel(1, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
  333. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  334. value |= BIT(BF_SRC_CFGX_SFIFO_ENA);
  335. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  336. break;
  337. default:
  338. dev_err(aio->cygaud->dev,
  339. "Port not supported %d\n", aio->portnum);
  340. status = -EINVAL;
  341. }
  342. return status;
  343. }
  344. static int audio_ssp_out_disable(struct cygnus_aio_port *aio)
  345. {
  346. u32 value;
  347. int status = 0;
  348. switch (aio->port_type) {
  349. case PORT_TDM:
  350. aio->streams_on &= ~PLAYBACK_STREAM_MASK;
  351. /* If both playback and capture are off */
  352. if (!aio->streams_on) {
  353. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  354. value &= ~BIT(I2S_OUT_CFGX_CLK_ENA);
  355. value &= ~BIT(I2S_OUT_CFGX_DATA_ENABLE);
  356. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  357. }
  358. /* set group_sync_dis = 1 */
  359. value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
  360. value |= BIT(aio->portnum);
  361. writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
  362. writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
  363. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  364. value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
  365. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  366. /* set group_sync_dis = 0 */
  367. value = readl(aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
  368. value &= ~BIT(aio->portnum);
  369. writel(value, aio->cygaud->audio + BF_SRC_GRP_SYNC_DIS_OFFSET);
  370. value = readl(aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  371. value &= ~BIT(I2S_OUT_STREAM_ENA);
  372. writel(value, aio->cygaud->audio + aio->regs.i2s_stream_cfg);
  373. /* IOP SW INIT on OUT_I2S_x */
  374. value = readl(aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
  375. value |= BIT(aio->portnum);
  376. writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
  377. value &= ~BIT(aio->portnum);
  378. writel(value, aio->cygaud->i2s_in + IOP_SW_INIT_LOGIC);
  379. break;
  380. case PORT_SPDIF:
  381. value = readl(aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
  382. value &= ~0x3;
  383. writel(value, aio->cygaud->audio + SPDIF_FORMAT_CFG_OFFSET);
  384. writel(0, aio->cygaud->audio + aio->regs.bf_sourcech_ctrl);
  385. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  386. value &= ~BIT(BF_SRC_CFGX_SFIFO_ENA);
  387. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  388. break;
  389. default:
  390. dev_err(aio->cygaud->dev,
  391. "Port not supported %d\n", aio->portnum);
  392. status = -EINVAL;
  393. }
  394. return status;
  395. }
  396. static int pll_configure_mclk(struct cygnus_audio *cygaud, u32 mclk,
  397. struct cygnus_aio_port *aio)
  398. {
  399. int i = 0, error;
  400. bool found = false;
  401. const struct pll_macro_entry *p_entry;
  402. struct clk *ch_clk;
  403. for (i = 0; i < ARRAY_SIZE(pll_predef_mclk); i++) {
  404. p_entry = &pll_predef_mclk[i];
  405. if (p_entry->mclk == mclk) {
  406. found = true;
  407. break;
  408. }
  409. }
  410. if (!found) {
  411. dev_err(cygaud->dev,
  412. "%s No valid mclk freq (%u) found!\n", __func__, mclk);
  413. return -EINVAL;
  414. }
  415. ch_clk = cygaud->audio_clk[p_entry->pll_ch_num];
  416. if ((aio->clk_trace.cap_en) && (!aio->clk_trace.cap_clk_en)) {
  417. error = clk_prepare_enable(ch_clk);
  418. if (error) {
  419. dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
  420. __func__, error);
  421. return error;
  422. }
  423. aio->clk_trace.cap_clk_en = true;
  424. }
  425. if ((aio->clk_trace.play_en) && (!aio->clk_trace.play_clk_en)) {
  426. error = clk_prepare_enable(ch_clk);
  427. if (error) {
  428. dev_err(cygaud->dev, "%s clk_prepare_enable failed %d\n",
  429. __func__, error);
  430. return error;
  431. }
  432. aio->clk_trace.play_clk_en = true;
  433. }
  434. error = clk_set_rate(ch_clk, mclk);
  435. if (error) {
  436. dev_err(cygaud->dev, "%s Set MCLK rate failed: %d\n",
  437. __func__, error);
  438. return error;
  439. }
  440. return p_entry->pll_ch_num;
  441. }
  442. static int cygnus_ssp_set_clocks(struct cygnus_aio_port *aio)
  443. {
  444. u32 value;
  445. u32 mask = 0xf;
  446. u32 sclk;
  447. u32 mclk_rate;
  448. unsigned int bit_rate;
  449. unsigned int ratio;
  450. bit_rate = aio->bit_per_frame * aio->lrclk;
  451. /*
  452. * Check if the bit clock can be generated from the given MCLK.
  453. * MCLK must be a perfect multiple of bit clock and must be one of the
  454. * following values... (2,4,6,8,10,12,14)
  455. */
  456. if ((aio->mclk % bit_rate) != 0)
  457. return -EINVAL;
  458. ratio = aio->mclk / bit_rate;
  459. switch (ratio) {
  460. case 2:
  461. case 4:
  462. case 6:
  463. case 8:
  464. case 10:
  465. case 12:
  466. case 14:
  467. mclk_rate = ratio / 2;
  468. break;
  469. default:
  470. dev_err(aio->cygaud->dev,
  471. "Invalid combination of MCLK and BCLK\n");
  472. dev_err(aio->cygaud->dev, "lrclk = %u, bits/frame = %u, mclk = %u\n",
  473. aio->lrclk, aio->bit_per_frame, aio->mclk);
  474. return -EINVAL;
  475. }
  476. /* Set sclk rate */
  477. switch (aio->port_type) {
  478. case PORT_TDM:
  479. sclk = aio->bit_per_frame;
  480. if (sclk == 512)
  481. sclk = 0;
  482. /* sclks_per_1fs_div = sclk cycles/32 */
  483. sclk /= 32;
  484. /* Set number of bitclks per frame */
  485. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  486. value &= ~(mask << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32);
  487. value |= sclk << I2S_OUT_CFGX_SCLKS_PER_1FS_DIV32;
  488. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  489. dev_dbg(aio->cygaud->dev,
  490. "SCLKS_PER_1FS_DIV32 = 0x%x\n", value);
  491. break;
  492. case PORT_SPDIF:
  493. break;
  494. default:
  495. dev_err(aio->cygaud->dev, "Unknown port type\n");
  496. return -EINVAL;
  497. }
  498. /* Set MCLK_RATE ssp port (spdif and ssp are the same) */
  499. value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  500. value &= ~(0xf << I2S_OUT_MCLKRATE_SHIFT);
  501. value |= (mclk_rate << I2S_OUT_MCLKRATE_SHIFT);
  502. writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  503. dev_dbg(aio->cygaud->dev, "mclk cfg reg = 0x%x\n", value);
  504. dev_dbg(aio->cygaud->dev, "bits per frame = %u, mclk = %u Hz, lrclk = %u Hz\n",
  505. aio->bit_per_frame, aio->mclk, aio->lrclk);
  506. return 0;
  507. }
  508. static int cygnus_ssp_hw_params(struct snd_pcm_substream *substream,
  509. struct snd_pcm_hw_params *params,
  510. struct snd_soc_dai *dai)
  511. {
  512. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
  513. int rate, bitres;
  514. u32 value;
  515. u32 mask = 0x1f;
  516. int ret = 0;
  517. dev_dbg(aio->cygaud->dev, "%s port = %d\n", __func__, aio->portnum);
  518. dev_dbg(aio->cygaud->dev, "params_channels %d\n",
  519. params_channels(params));
  520. dev_dbg(aio->cygaud->dev, "rate %d\n", params_rate(params));
  521. dev_dbg(aio->cygaud->dev, "format %d\n", params_format(params));
  522. rate = params_rate(params);
  523. switch (aio->mode) {
  524. case CYGNUS_SSPMODE_TDM:
  525. if ((rate == 192000) && (params_channels(params) > 4)) {
  526. dev_err(aio->cygaud->dev, "Cannot run %d channels at %dHz\n",
  527. params_channels(params), rate);
  528. return -EINVAL;
  529. }
  530. break;
  531. case CYGNUS_SSPMODE_I2S:
  532. aio->bit_per_frame = 64; /* I2S must be 64 bit per frame */
  533. break;
  534. default:
  535. dev_err(aio->cygaud->dev,
  536. "%s port running in unknown mode\n", __func__);
  537. return -EINVAL;
  538. }
  539. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  540. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  541. value &= ~BIT(BF_SRC_CFGX_BUFFER_PAIR_ENABLE);
  542. value &= ~BIT(BF_SRC_CFGX_SAMPLE_CH_MODE);
  543. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  544. switch (params_format(params)) {
  545. case SNDRV_PCM_FORMAT_S16_LE:
  546. bitres = 16;
  547. break;
  548. case SNDRV_PCM_FORMAT_S32_LE:
  549. /* 32 bit mode is coded as 0 */
  550. bitres = 0;
  551. break;
  552. default:
  553. return -EINVAL;
  554. }
  555. value = readl(aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  556. value &= ~(mask << BF_SRC_CFGX_BIT_RES);
  557. value |= (bitres << BF_SRC_CFGX_BIT_RES);
  558. writel(value, aio->cygaud->audio + aio->regs.bf_sourcech_cfg);
  559. } else {
  560. switch (params_format(params)) {
  561. case SNDRV_PCM_FORMAT_S16_LE:
  562. value = readl(aio->cygaud->audio +
  563. aio->regs.bf_destch_cfg);
  564. value |= BIT(BF_DST_CFGX_CAP_MODE);
  565. writel(value, aio->cygaud->audio +
  566. aio->regs.bf_destch_cfg);
  567. break;
  568. case SNDRV_PCM_FORMAT_S32_LE:
  569. value = readl(aio->cygaud->audio +
  570. aio->regs.bf_destch_cfg);
  571. value &= ~BIT(BF_DST_CFGX_CAP_MODE);
  572. writel(value, aio->cygaud->audio +
  573. aio->regs.bf_destch_cfg);
  574. break;
  575. default:
  576. return -EINVAL;
  577. }
  578. }
  579. aio->lrclk = rate;
  580. if (!aio->is_slave)
  581. ret = cygnus_ssp_set_clocks(aio);
  582. return ret;
  583. }
  584. /*
  585. * This function sets the mclk frequency for pll clock
  586. */
  587. static int cygnus_ssp_set_sysclk(struct snd_soc_dai *dai,
  588. int clk_id, unsigned int freq, int dir)
  589. {
  590. int sel;
  591. u32 value;
  592. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
  593. struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
  594. dev_dbg(aio->cygaud->dev,
  595. "%s Enter port = %d\n", __func__, aio->portnum);
  596. sel = pll_configure_mclk(cygaud, freq, aio);
  597. if (sel < 0) {
  598. dev_err(aio->cygaud->dev,
  599. "%s Setting mclk failed.\n", __func__);
  600. return -EINVAL;
  601. }
  602. aio->mclk = freq;
  603. dev_dbg(aio->cygaud->dev, "%s Setting MCLKSEL to %d\n", __func__, sel);
  604. value = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  605. value &= ~(0xf << I2S_OUT_PLLCLKSEL_SHIFT);
  606. value |= (sel << I2S_OUT_PLLCLKSEL_SHIFT);
  607. writel(value, aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  608. return 0;
  609. }
  610. static int cygnus_ssp_startup(struct snd_pcm_substream *substream,
  611. struct snd_soc_dai *dai)
  612. {
  613. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
  614. snd_soc_dai_set_dma_data(dai, substream, aio);
  615. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  616. aio->clk_trace.play_en = true;
  617. else
  618. aio->clk_trace.cap_en = true;
  619. substream->runtime->hw.rate_min = CYGNUS_RATE_MIN;
  620. substream->runtime->hw.rate_max = CYGNUS_RATE_MAX;
  621. snd_pcm_hw_constraint_list(substream->runtime, 0,
  622. SNDRV_PCM_HW_PARAM_RATE, &cygnus_rate_constraint);
  623. return 0;
  624. }
  625. static void cygnus_ssp_shutdown(struct snd_pcm_substream *substream,
  626. struct snd_soc_dai *dai)
  627. {
  628. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
  629. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  630. aio->clk_trace.play_en = false;
  631. else
  632. aio->clk_trace.cap_en = false;
  633. if (!aio->is_slave) {
  634. u32 val;
  635. val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  636. val &= CYGNUS_PLLCLKSEL_MASK;
  637. if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
  638. dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
  639. val);
  640. return;
  641. }
  642. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
  643. if (aio->clk_trace.play_clk_en) {
  644. clk_disable_unprepare(aio->cygaud->
  645. audio_clk[val]);
  646. aio->clk_trace.play_clk_en = false;
  647. }
  648. } else {
  649. if (aio->clk_trace.cap_clk_en) {
  650. clk_disable_unprepare(aio->cygaud->
  651. audio_clk[val]);
  652. aio->clk_trace.cap_clk_en = false;
  653. }
  654. }
  655. }
  656. }
  657. /*
  658. * Bit Update Notes
  659. * 31 Yes TDM Mode (1 = TDM, 0 = i2s)
  660. * 30 Yes Slave Mode (1 = Slave, 0 = Master)
  661. * 29:26 No Sclks per frame
  662. * 25:18 Yes FS Width
  663. * 17:14 No Valid Slots
  664. * 13 No Bits (1 = 16 bits, 0 = 32 bits)
  665. * 12:08 No Bits per samp
  666. * 07 Yes Justifcation (1 = LSB, 0 = MSB)
  667. * 06 Yes Alignment (1 = Delay 1 clk, 0 = no delay
  668. * 05 Yes SCLK polarity (1 = Rising, 0 = Falling)
  669. * 04 Yes LRCLK Polarity (1 = High for left, 0 = Low for left)
  670. * 03:02 Yes Reserved - write as zero
  671. * 01 No Data Enable
  672. * 00 No CLK Enable
  673. */
  674. #define I2S_OUT_CFG_REG_UPDATE_MASK 0x3C03FF03
  675. /* Input cfg is same as output, but the FS width is not a valid field */
  676. #define I2S_IN_CFG_REG_UPDATE_MASK (I2S_OUT_CFG_REG_UPDATE_MASK | 0x03FC0000)
  677. int cygnus_ssp_set_custom_fsync_width(struct snd_soc_dai *cpu_dai, int len)
  678. {
  679. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
  680. if ((len > 0) && (len < 256)) {
  681. aio->fsync_width = len;
  682. return 0;
  683. } else {
  684. return -EINVAL;
  685. }
  686. }
  687. EXPORT_SYMBOL_GPL(cygnus_ssp_set_custom_fsync_width);
  688. static int cygnus_ssp_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
  689. {
  690. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
  691. u32 ssp_curcfg;
  692. u32 ssp_newcfg;
  693. u32 ssp_outcfg;
  694. u32 ssp_incfg;
  695. u32 val;
  696. u32 mask;
  697. dev_dbg(aio->cygaud->dev, "%s Enter fmt: %x\n", __func__, fmt);
  698. if (aio->port_type == PORT_SPDIF)
  699. return -EINVAL;
  700. ssp_newcfg = 0;
  701. switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
  702. case SND_SOC_DAIFMT_CBM_CFM:
  703. ssp_newcfg |= BIT(I2S_OUT_CFGX_SLAVE_MODE);
  704. aio->is_slave = 1;
  705. break;
  706. case SND_SOC_DAIFMT_CBS_CFS:
  707. ssp_newcfg &= ~BIT(I2S_OUT_CFGX_SLAVE_MODE);
  708. aio->is_slave = 0;
  709. break;
  710. default:
  711. return -EINVAL;
  712. }
  713. switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
  714. case SND_SOC_DAIFMT_I2S:
  715. ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
  716. ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
  717. aio->mode = CYGNUS_SSPMODE_I2S;
  718. break;
  719. case SND_SOC_DAIFMT_DSP_A:
  720. case SND_SOC_DAIFMT_DSP_B:
  721. ssp_newcfg |= BIT(I2S_OUT_CFGX_TDM_MODE);
  722. /* DSP_A = data after FS, DSP_B = data during FS */
  723. if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A)
  724. ssp_newcfg |= BIT(I2S_OUT_CFGX_DATA_ALIGNMENT);
  725. if ((aio->fsync_width > 0) && (aio->fsync_width < 256))
  726. ssp_newcfg |=
  727. (aio->fsync_width << I2S_OUT_CFGX_FSYNC_WIDTH);
  728. else
  729. ssp_newcfg |= BIT(I2S_OUT_CFGX_FSYNC_WIDTH);
  730. aio->mode = CYGNUS_SSPMODE_TDM;
  731. break;
  732. default:
  733. return -EINVAL;
  734. }
  735. /*
  736. * SSP out cfg.
  737. * Retain bits we do not want to update, then OR in new bits
  738. */
  739. ssp_curcfg = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  740. ssp_outcfg = (ssp_curcfg & I2S_OUT_CFG_REG_UPDATE_MASK) | ssp_newcfg;
  741. writel(ssp_outcfg, aio->cygaud->audio + aio->regs.i2s_cfg);
  742. /*
  743. * SSP in cfg.
  744. * Retain bits we do not want to update, then OR in new bits
  745. */
  746. ssp_curcfg = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
  747. ssp_incfg = (ssp_curcfg & I2S_IN_CFG_REG_UPDATE_MASK) | ssp_newcfg;
  748. writel(ssp_incfg, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
  749. val = readl(aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  750. /*
  751. * Configure the word clk and bit clk as output or tristate
  752. * Each port has 4 bits for controlling its pins.
  753. * Shift the mask based upon port number.
  754. */
  755. mask = BIT(AUD_MISC_SEROUT_LRCK_OE)
  756. | BIT(AUD_MISC_SEROUT_SCLK_OE)
  757. | BIT(AUD_MISC_SEROUT_MCLK_OE);
  758. mask = mask << (aio->portnum * 4);
  759. if (aio->is_slave)
  760. /* Set bit for tri-state */
  761. val |= mask;
  762. else
  763. /* Clear bit for drive */
  764. val &= ~mask;
  765. dev_dbg(aio->cygaud->dev, "%s Set OE bits 0x%x\n", __func__, val);
  766. writel(val, aio->cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  767. return 0;
  768. }
  769. static int cygnus_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
  770. struct snd_soc_dai *dai)
  771. {
  772. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(dai);
  773. struct cygnus_audio *cygaud = snd_soc_dai_get_drvdata(dai);
  774. dev_dbg(aio->cygaud->dev,
  775. "%s cmd %d at port = %d\n", __func__, cmd, aio->portnum);
  776. switch (cmd) {
  777. case SNDRV_PCM_TRIGGER_START:
  778. case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
  779. case SNDRV_PCM_TRIGGER_RESUME:
  780. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  781. audio_ssp_out_enable(aio);
  782. else
  783. audio_ssp_in_enable(aio);
  784. cygaud->active_ports++;
  785. break;
  786. case SNDRV_PCM_TRIGGER_STOP:
  787. case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
  788. case SNDRV_PCM_TRIGGER_SUSPEND:
  789. if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
  790. audio_ssp_out_disable(aio);
  791. else
  792. audio_ssp_in_disable(aio);
  793. cygaud->active_ports--;
  794. break;
  795. default:
  796. return -EINVAL;
  797. }
  798. return 0;
  799. }
  800. static int cygnus_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
  801. unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
  802. {
  803. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
  804. u32 value;
  805. int bits_per_slot = 0; /* default to 32-bits per slot */
  806. int frame_bits;
  807. unsigned int active_slots;
  808. bool found = false;
  809. int i;
  810. if (tx_mask != rx_mask) {
  811. dev_err(aio->cygaud->dev,
  812. "%s tx_mask must equal rx_mask\n", __func__);
  813. return -EINVAL;
  814. }
  815. active_slots = hweight32(tx_mask);
  816. if (active_slots > 16)
  817. return -EINVAL;
  818. /* Slot value must be even */
  819. if (active_slots % 2)
  820. return -EINVAL;
  821. /* We encode 16 slots as 0 in the reg */
  822. if (active_slots == 16)
  823. active_slots = 0;
  824. /* Slot Width is either 16 or 32 */
  825. switch (slot_width) {
  826. case 16:
  827. bits_per_slot = 1;
  828. break;
  829. case 32:
  830. bits_per_slot = 0;
  831. break;
  832. default:
  833. bits_per_slot = 0;
  834. dev_warn(aio->cygaud->dev,
  835. "%s Defaulting Slot Width to 32\n", __func__);
  836. }
  837. frame_bits = slots * slot_width;
  838. for (i = 0; i < ARRAY_SIZE(ssp_valid_tdm_framesize); i++) {
  839. if (ssp_valid_tdm_framesize[i] == frame_bits) {
  840. found = true;
  841. break;
  842. }
  843. }
  844. if (!found) {
  845. dev_err(aio->cygaud->dev,
  846. "%s In TDM mode, frame bits INVALID (%d)\n",
  847. __func__, frame_bits);
  848. return -EINVAL;
  849. }
  850. aio->bit_per_frame = frame_bits;
  851. dev_dbg(aio->cygaud->dev, "%s active_slots %u, bits per frame %d\n",
  852. __func__, active_slots, frame_bits);
  853. /* Set capture side of ssp port */
  854. value = readl(aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
  855. value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
  856. value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
  857. value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
  858. value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
  859. writel(value, aio->cygaud->i2s_in + aio->regs.i2s_cap_cfg);
  860. /* Set playback side of ssp port */
  861. value = readl(aio->cygaud->audio + aio->regs.i2s_cfg);
  862. value &= ~(0xf << I2S_OUT_CFGX_VALID_SLOT);
  863. value |= (active_slots << I2S_OUT_CFGX_VALID_SLOT);
  864. value &= ~BIT(I2S_OUT_CFGX_BITS_PER_SLOT);
  865. value |= (bits_per_slot << I2S_OUT_CFGX_BITS_PER_SLOT);
  866. writel(value, aio->cygaud->audio + aio->regs.i2s_cfg);
  867. return 0;
  868. }
  869. #ifdef CONFIG_PM_SLEEP
  870. static int cygnus_ssp_suspend(struct snd_soc_dai *cpu_dai)
  871. {
  872. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
  873. if (!aio->is_slave) {
  874. u32 val;
  875. val = readl(aio->cygaud->audio + aio->regs.i2s_mclk_cfg);
  876. val &= CYGNUS_PLLCLKSEL_MASK;
  877. if (val >= ARRAY_SIZE(aio->cygaud->audio_clk)) {
  878. dev_err(aio->cygaud->dev, "Clk index %u is out of bounds\n",
  879. val);
  880. return -EINVAL;
  881. }
  882. if (aio->clk_trace.cap_clk_en)
  883. clk_disable_unprepare(aio->cygaud->audio_clk[val]);
  884. if (aio->clk_trace.play_clk_en)
  885. clk_disable_unprepare(aio->cygaud->audio_clk[val]);
  886. aio->pll_clk_num = val;
  887. }
  888. return 0;
  889. }
  890. static int cygnus_ssp_resume(struct snd_soc_dai *cpu_dai)
  891. {
  892. struct cygnus_aio_port *aio = cygnus_dai_get_portinfo(cpu_dai);
  893. int error;
  894. if (!aio->is_slave) {
  895. if (aio->clk_trace.cap_clk_en) {
  896. error = clk_prepare_enable(aio->cygaud->
  897. audio_clk[aio->pll_clk_num]);
  898. if (error) {
  899. dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
  900. __func__);
  901. return -EINVAL;
  902. }
  903. }
  904. if (aio->clk_trace.play_clk_en) {
  905. error = clk_prepare_enable(aio->cygaud->
  906. audio_clk[aio->pll_clk_num]);
  907. if (error) {
  908. if (aio->clk_trace.cap_clk_en)
  909. clk_disable_unprepare(aio->cygaud->
  910. audio_clk[aio->pll_clk_num]);
  911. dev_err(aio->cygaud->dev, "%s clk_prepare_enable failed\n",
  912. __func__);
  913. return -EINVAL;
  914. }
  915. }
  916. }
  917. return 0;
  918. }
  919. #else
  920. #define cygnus_ssp_suspend NULL
  921. #define cygnus_ssp_resume NULL
  922. #endif
  923. static const struct snd_soc_dai_ops cygnus_ssp_dai_ops = {
  924. .startup = cygnus_ssp_startup,
  925. .shutdown = cygnus_ssp_shutdown,
  926. .trigger = cygnus_ssp_trigger,
  927. .hw_params = cygnus_ssp_hw_params,
  928. .set_fmt = cygnus_ssp_set_fmt,
  929. .set_sysclk = cygnus_ssp_set_sysclk,
  930. .set_tdm_slot = cygnus_set_dai_tdm_slot,
  931. };
  932. static const struct snd_soc_dai_ops cygnus_spdif_dai_ops = {
  933. .startup = cygnus_ssp_startup,
  934. .shutdown = cygnus_ssp_shutdown,
  935. .trigger = cygnus_ssp_trigger,
  936. .hw_params = cygnus_ssp_hw_params,
  937. .set_sysclk = cygnus_ssp_set_sysclk,
  938. };
  939. #define INIT_CPU_DAI(num) { \
  940. .name = "cygnus-ssp" #num, \
  941. .playback = { \
  942. .channels_min = 2, \
  943. .channels_max = 16, \
  944. .rates = SNDRV_PCM_RATE_KNOT, \
  945. .formats = SNDRV_PCM_FMTBIT_S16_LE | \
  946. SNDRV_PCM_FMTBIT_S32_LE, \
  947. }, \
  948. .capture = { \
  949. .channels_min = 2, \
  950. .channels_max = 16, \
  951. .rates = SNDRV_PCM_RATE_KNOT, \
  952. .formats = SNDRV_PCM_FMTBIT_S16_LE | \
  953. SNDRV_PCM_FMTBIT_S32_LE, \
  954. }, \
  955. .ops = &cygnus_ssp_dai_ops, \
  956. .suspend = cygnus_ssp_suspend, \
  957. .resume = cygnus_ssp_resume, \
  958. }
  959. static const struct snd_soc_dai_driver cygnus_ssp_dai_info[] = {
  960. INIT_CPU_DAI(0),
  961. INIT_CPU_DAI(1),
  962. INIT_CPU_DAI(2),
  963. };
  964. static const struct snd_soc_dai_driver cygnus_spdif_dai_info = {
  965. .name = "cygnus-spdif",
  966. .playback = {
  967. .channels_min = 2,
  968. .channels_max = 2,
  969. .rates = SNDRV_PCM_RATE_KNOT,
  970. .formats = SNDRV_PCM_FMTBIT_S16_LE |
  971. SNDRV_PCM_FMTBIT_S32_LE,
  972. },
  973. .ops = &cygnus_spdif_dai_ops,
  974. .suspend = cygnus_ssp_suspend,
  975. .resume = cygnus_ssp_resume,
  976. };
  977. static struct snd_soc_dai_driver cygnus_ssp_dai[CYGNUS_MAX_PORTS];
  978. static const struct snd_soc_component_driver cygnus_ssp_component = {
  979. .name = "cygnus-audio",
  980. };
  981. /*
  982. * Return < 0 if error
  983. * Return 0 if disabled
  984. * Return 1 if enabled and node is parsed successfully
  985. */
  986. static int parse_ssp_child_node(struct platform_device *pdev,
  987. struct device_node *dn,
  988. struct cygnus_audio *cygaud,
  989. struct snd_soc_dai_driver *p_dai)
  990. {
  991. struct cygnus_aio_port *aio;
  992. struct cygnus_ssp_regs ssp_regs[3];
  993. u32 rawval;
  994. int portnum = -1;
  995. enum cygnus_audio_port_type port_type;
  996. if (of_property_read_u32(dn, "reg", &rawval)) {
  997. dev_err(&pdev->dev, "Missing reg property\n");
  998. return -EINVAL;
  999. }
  1000. portnum = rawval;
  1001. switch (rawval) {
  1002. case 0:
  1003. ssp_regs[0] = INIT_SSP_REGS(0);
  1004. port_type = PORT_TDM;
  1005. break;
  1006. case 1:
  1007. ssp_regs[1] = INIT_SSP_REGS(1);
  1008. port_type = PORT_TDM;
  1009. break;
  1010. case 2:
  1011. ssp_regs[2] = INIT_SSP_REGS(2);
  1012. port_type = PORT_TDM;
  1013. break;
  1014. case 3:
  1015. port_type = PORT_SPDIF;
  1016. break;
  1017. default:
  1018. dev_err(&pdev->dev, "Bad value for reg %u\n", rawval);
  1019. return -EINVAL;
  1020. }
  1021. aio = &cygaud->portinfo[portnum];
  1022. aio->cygaud = cygaud;
  1023. aio->portnum = portnum;
  1024. aio->port_type = port_type;
  1025. aio->fsync_width = -1;
  1026. switch (port_type) {
  1027. case PORT_TDM:
  1028. aio->regs = ssp_regs[portnum];
  1029. *p_dai = cygnus_ssp_dai_info[portnum];
  1030. aio->mode = CYGNUS_SSPMODE_UNKNOWN;
  1031. break;
  1032. case PORT_SPDIF:
  1033. aio->regs.bf_sourcech_cfg = BF_SRC_CFG3_OFFSET;
  1034. aio->regs.bf_sourcech_ctrl = BF_SRC_CTRL3_OFFSET;
  1035. aio->regs.i2s_mclk_cfg = SPDIF_MCLK_CFG_OFFSET;
  1036. aio->regs.i2s_stream_cfg = SPDIF_STREAM_CFG_OFFSET;
  1037. *p_dai = cygnus_spdif_dai_info;
  1038. /* For the purposes of this code SPDIF can be I2S mode */
  1039. aio->mode = CYGNUS_SSPMODE_I2S;
  1040. break;
  1041. default:
  1042. dev_err(&pdev->dev, "Bad value for port_type %d\n", port_type);
  1043. return -EINVAL;
  1044. }
  1045. dev_dbg(&pdev->dev, "%s portnum = %d\n", __func__, aio->portnum);
  1046. aio->streams_on = 0;
  1047. aio->cygaud->dev = &pdev->dev;
  1048. aio->clk_trace.play_en = false;
  1049. aio->clk_trace.cap_en = false;
  1050. audio_ssp_init_portregs(aio);
  1051. return 0;
  1052. }
  1053. static int audio_clk_init(struct platform_device *pdev,
  1054. struct cygnus_audio *cygaud)
  1055. {
  1056. int i;
  1057. char clk_name[PROP_LEN_MAX];
  1058. for (i = 0; i < ARRAY_SIZE(cygaud->audio_clk); i++) {
  1059. snprintf(clk_name, PROP_LEN_MAX, "ch%d_audio", i);
  1060. cygaud->audio_clk[i] = devm_clk_get(&pdev->dev, clk_name);
  1061. if (IS_ERR(cygaud->audio_clk[i]))
  1062. return PTR_ERR(cygaud->audio_clk[i]);
  1063. }
  1064. return 0;
  1065. }
  1066. static int cygnus_ssp_probe(struct platform_device *pdev)
  1067. {
  1068. struct device *dev = &pdev->dev;
  1069. struct device_node *child_node;
  1070. struct resource *res;
  1071. struct cygnus_audio *cygaud;
  1072. int err = -EINVAL;
  1073. int node_count;
  1074. int active_port_count;
  1075. cygaud = devm_kzalloc(dev, sizeof(struct cygnus_audio), GFP_KERNEL);
  1076. if (!cygaud)
  1077. return -ENOMEM;
  1078. dev_set_drvdata(dev, cygaud);
  1079. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aud");
  1080. cygaud->audio = devm_ioremap_resource(dev, res);
  1081. if (IS_ERR(cygaud->audio))
  1082. return PTR_ERR(cygaud->audio);
  1083. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "i2s_in");
  1084. cygaud->i2s_in = devm_ioremap_resource(dev, res);
  1085. if (IS_ERR(cygaud->i2s_in))
  1086. return PTR_ERR(cygaud->i2s_in);
  1087. /* Tri-state all controlable pins until we know that we need them */
  1088. writel(CYGNUS_SSP_TRISTATE_MASK,
  1089. cygaud->audio + AUD_MISC_SEROUT_OE_REG_BASE);
  1090. node_count = of_get_child_count(pdev->dev.of_node);
  1091. if ((node_count < 1) || (node_count > CYGNUS_MAX_PORTS)) {
  1092. dev_err(dev, "child nodes is %d. Must be between 1 and %d\n",
  1093. node_count, CYGNUS_MAX_PORTS);
  1094. return -EINVAL;
  1095. }
  1096. active_port_count = 0;
  1097. for_each_available_child_of_node(pdev->dev.of_node, child_node) {
  1098. err = parse_ssp_child_node(pdev, child_node, cygaud,
  1099. &cygnus_ssp_dai[active_port_count]);
  1100. /* negative is err, 0 is active and good, 1 is disabled */
  1101. if (err < 0)
  1102. return err;
  1103. else if (!err) {
  1104. dev_dbg(dev, "Activating DAI: %s\n",
  1105. cygnus_ssp_dai[active_port_count].name);
  1106. active_port_count++;
  1107. }
  1108. }
  1109. cygaud->dev = dev;
  1110. cygaud->active_ports = 0;
  1111. dev_dbg(dev, "Registering %d DAIs\n", active_port_count);
  1112. err = snd_soc_register_component(dev, &cygnus_ssp_component,
  1113. cygnus_ssp_dai, active_port_count);
  1114. if (err) {
  1115. dev_err(dev, "snd_soc_register_dai failed\n");
  1116. return err;
  1117. }
  1118. cygaud->irq_num = platform_get_irq(pdev, 0);
  1119. if (cygaud->irq_num <= 0) {
  1120. dev_err(dev, "platform_get_irq failed\n");
  1121. err = cygaud->irq_num;
  1122. goto err_irq;
  1123. }
  1124. err = audio_clk_init(pdev, cygaud);
  1125. if (err) {
  1126. dev_err(dev, "audio clock initialization failed\n");
  1127. goto err_irq;
  1128. }
  1129. err = cygnus_soc_platform_register(dev, cygaud);
  1130. if (err) {
  1131. dev_err(dev, "platform reg error %d\n", err);
  1132. goto err_irq;
  1133. }
  1134. return 0;
  1135. err_irq:
  1136. snd_soc_unregister_component(dev);
  1137. return err;
  1138. }
  1139. static int cygnus_ssp_remove(struct platform_device *pdev)
  1140. {
  1141. cygnus_soc_platform_unregister(&pdev->dev);
  1142. snd_soc_unregister_component(&pdev->dev);
  1143. return 0;
  1144. }
  1145. static const struct of_device_id cygnus_ssp_of_match[] = {
  1146. { .compatible = "brcm,cygnus-audio" },
  1147. {},
  1148. };
  1149. MODULE_DEVICE_TABLE(of, cygnus_ssp_of_match);
  1150. static struct platform_driver cygnus_ssp_driver = {
  1151. .probe = cygnus_ssp_probe,
  1152. .remove = cygnus_ssp_remove,
  1153. .driver = {
  1154. .name = "cygnus-ssp",
  1155. .of_match_table = cygnus_ssp_of_match,
  1156. },
  1157. };
  1158. module_platform_driver(cygnus_ssp_driver);
  1159. MODULE_ALIAS("platform:cygnus-ssp");
  1160. MODULE_LICENSE("GPL v2");
  1161. MODULE_AUTHOR("Broadcom");
  1162. MODULE_DESCRIPTION("Cygnus ASoC SSP Interface");