diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 12:08:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-04 12:08:25 -0400 |
commit | b77279bc2e81545b20824da701b349272a78e4e7 (patch) | |
tree | d8f3a8ddf544cf201f8bdcb587cf360571487e5c /sound/soc/fsl/fsl_ssi.c | |
parent | 15b588303155b22edd559672905db8e59a44ef9a (diff) | |
parent | 16088cb6c02d0b766b9b8d7edff98da7f1c93205 (diff) |
Merge tag 'sound-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound into next
Pull sound updates from Takashi Iwai:
"At this time, majority of changes come from ASoC world while we got a
few new drivers in other places for FireWire and USB. There have been
lots of ASoC core cleanups / refactoring, but very little visible to
external users.
ASoC:
- Support for specifying aux CODECs in DT
- Removal of the deprecated mux and enum macros
- More moves towards full componentisation
- Removal of some unused I/O code
- Lots of cleanups, fixes and enhancements to the davinci, Freescale,
Haswell and Realtek drivers
- Several drivers exposed directly in Kconfig for use with
simple-card
- GPIO descriptor support for jacks
- More updates and fixes to the Freescale SSI, Intel and rsnd drivers
- New drivers for Cirrus CS42L56, Realtek RT5639, RT5642 and RT5651
and ST STA350, Analog Devices ADAU1361, ADAU1381, ADAU1761 and
ADAU1781, and Realtek RT5677
HD-audio:
- Clean up Dell headset quirks
- Noise fixes for Dell and Sony laptops
- Thinkpad T440 dock fix
- Realtek codec updates (ALC293,ALC233,ALC3235)
- Tegra HD-audio HDMI support
FireWire-audio:
- FireWire audio stack enhancement (AMDTP, MIDI), support for
incoming isochronous stream and duplex streams with timestamp
synchronization
- BeBoB-based devices support
- Fireworks-based device support
USB-audio:
- Behringer BCD2000 USB device support
Misc:
- Clean up of a few old drivers, atmel, fm801, etc"
* tag 'sound-3.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (480 commits)
ASoC: Fix wrong argument for card remove callbacks
ASoC: free jack GPIOs before the sound card is freed
ALSA: firewire-lib: Remove a comment about restriction of asynchronous operation
ASoC: cache: Fix error code when not using ASoC level cache
ALSA: hda/realtek - Fix COEF widget NID for ALC260 replacer fixup
ALSA: hda/realtek - Correction of fixup codes for PB V7900 laptop
ALSA: firewire-lib: Use IEC 61883-6 compliant labels for Raw Audio data
ASoC: add RT5677 CODEC driver
ASoC: intel: The Baytrail/MAX98090 driver depends on I2C
ASoC: rt5640: Add the function "get_clk_info" to RL6231 shared support
ASoC: rt5640: Add the function of the PLL clock calculation to RL6231 shared support
ASoC: rt5640: Add RL6231 class device shared support for RT5640, RT5645 and RT5651
ASoC: cache: Fix possible ZERO_SIZE_PTR pointer dereferencing error.
ASoC: Add helper functions to cast from DAPM context to CODEC/platform
ALSA: bebob: sizeof() vs ARRAY_SIZE() typo
ASoC: wm9713: correct mono out PGA sources
ALSA: synth: emux: soundfont.c: Cleaning up memory leak
ASoC: fsl: Remove dependencies of boards for SND_SOC_EUKREA_TLV320
ASoC: fsl-ssi: Use regmap
ASoC: fsl-ssi: reorder and document fsl_ssi_private
...
Diffstat (limited to 'sound/soc/fsl/fsl_ssi.c')
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 1414 |
1 files changed, 620 insertions, 794 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..9bfef55d77d1 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -35,11 +35,11 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
38 | #include <linux/debugfs.h> | ||
39 | #include <linux/device.h> | 38 | #include <linux/device.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
42 | #include <linux/of.h> | ||
43 | #include <linux/of_address.h> | 43 | #include <linux/of_address.h> |
44 | #include <linux/of_irq.h> | 44 | #include <linux/of_irq.h> |
45 | #include <linux/of_platform.h> | 45 | #include <linux/of_platform.h> |
@@ -54,25 +54,6 @@ | |||
54 | #include "fsl_ssi.h" | 54 | #include "fsl_ssi.h" |
55 | #include "imx-pcm.h" | 55 | #include "imx-pcm.h" |
56 | 56 | ||
57 | #ifdef PPC | ||
58 | #define read_ssi(addr) in_be32(addr) | ||
59 | #define write_ssi(val, addr) out_be32(addr, val) | ||
60 | #define write_ssi_mask(addr, clear, set) clrsetbits_be32(addr, clear, set) | ||
61 | #else | ||
62 | #define read_ssi(addr) readl(addr) | ||
63 | #define write_ssi(val, addr) writel(val, addr) | ||
64 | /* | ||
65 | * FIXME: Proper locking should be added at write_ssi_mask caller level | ||
66 | * to ensure this register read/modify/write sequence is race free. | ||
67 | */ | ||
68 | static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | ||
69 | { | ||
70 | u32 val = readl(addr); | ||
71 | val = (val & ~clear) | set; | ||
72 | writel(val, addr); | ||
73 | } | ||
74 | #endif | ||
75 | |||
76 | /** | 57 | /** |
77 | * FSLSSI_I2S_RATES: sample rates supported by the I2S | 58 | * FSLSSI_I2S_RATES: sample rates supported by the I2S |
78 | * | 59 | * |
@@ -113,8 +94,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | |||
113 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ | 94 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ |
114 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ | 95 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ |
115 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) | 96 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) |
116 | #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) | ||
117 | |||
118 | 97 | ||
119 | enum fsl_ssi_type { | 98 | enum fsl_ssi_type { |
120 | FSL_SSI_MCP8610, | 99 | FSL_SSI_MCP8610, |
@@ -134,87 +113,152 @@ struct fsl_ssi_rxtx_reg_val { | |||
134 | struct fsl_ssi_reg_val rx; | 113 | struct fsl_ssi_reg_val rx; |
135 | struct fsl_ssi_reg_val tx; | 114 | struct fsl_ssi_reg_val tx; |
136 | }; | 115 | }; |
116 | static const struct regmap_config fsl_ssi_regconfig = { | ||
117 | .max_register = CCSR_SSI_SACCDIS, | ||
118 | .reg_bits = 32, | ||
119 | .val_bits = 32, | ||
120 | .reg_stride = 4, | ||
121 | .val_format_endian = REGMAP_ENDIAN_NATIVE, | ||
122 | }; | ||
123 | |||
124 | struct fsl_ssi_soc_data { | ||
125 | bool imx; | ||
126 | bool offline_config; | ||
127 | u32 sisr_write_mask; | ||
128 | }; | ||
137 | 129 | ||
138 | /** | 130 | /** |
139 | * fsl_ssi_private: per-SSI private data | 131 | * fsl_ssi_private: per-SSI private data |
140 | * | 132 | * |
141 | * @ssi: pointer to the SSI's registers | 133 | * @reg: Pointer to the regmap registers |
142 | * @ssi_phys: physical address of the SSI registers | ||
143 | * @irq: IRQ of this SSI | 134 | * @irq: IRQ of this SSI |
144 | * @playback: the number of playback streams opened | 135 | * @cpu_dai_drv: CPU DAI driver for this device |
145 | * @capture: the number of capture streams opened | 136 | * |
146 | * @cpu_dai: the CPU DAI for this device | 137 | * @dai_fmt: DAI configuration this device is currently used with |
147 | * @dev_attr: the sysfs device attribute structure | 138 | * @i2s_mode: i2s and network mode configuration of the device. Is used to |
148 | * @stats: SSI statistics | 139 | * switch between normal and i2s/network mode |
149 | * @name: name for this device | 140 | * mode depending on the number of channels |
141 | * @use_dma: DMA is used or FIQ with stream filter | ||
142 | * @use_dual_fifo: DMA with support for both FIFOs used | ||
143 | * @fifo_deph: Depth of the SSI FIFOs | ||
144 | * @rxtx_reg_val: Specific register settings for receive/transmit configuration | ||
145 | * | ||
146 | * @clk: SSI clock | ||
147 | * @baudclk: SSI baud clock for master mode | ||
148 | * @baudclk_streams: Active streams that are using baudclk | ||
149 | * @bitclk_freq: bitclock frequency set by .set_dai_sysclk | ||
150 | * | ||
151 | * @dma_params_tx: DMA transmit parameters | ||
152 | * @dma_params_rx: DMA receive parameters | ||
153 | * @ssi_phys: physical address of the SSI registers | ||
154 | * | ||
155 | * @fiq_params: FIQ stream filtering parameters | ||
156 | * | ||
157 | * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card | ||
158 | * | ||
159 | * @dbg_stats: Debugging statistics | ||
160 | * | ||
161 | * @soc: SoC specifc data | ||
150 | */ | 162 | */ |
151 | struct fsl_ssi_private { | 163 | struct fsl_ssi_private { |
152 | struct ccsr_ssi __iomem *ssi; | 164 | struct regmap *regs; |
153 | dma_addr_t ssi_phys; | ||
154 | unsigned int irq; | 165 | unsigned int irq; |
155 | unsigned int fifo_depth; | ||
156 | struct snd_soc_dai_driver cpu_dai_drv; | 166 | struct snd_soc_dai_driver cpu_dai_drv; |
157 | struct platform_device *pdev; | ||
158 | 167 | ||
159 | enum fsl_ssi_type hw_type; | 168 | unsigned int dai_fmt; |
160 | bool new_binding; | 169 | u8 i2s_mode; |
161 | bool ssi_on_imx; | ||
162 | bool imx_ac97; | ||
163 | bool use_dma; | 170 | bool use_dma; |
164 | bool baudclk_locked; | ||
165 | bool irq_stats; | ||
166 | bool offline_config; | ||
167 | bool use_dual_fifo; | 171 | bool use_dual_fifo; |
168 | u8 i2s_mode; | 172 | unsigned int fifo_depth; |
169 | spinlock_t baudclk_lock; | 173 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; |
170 | struct clk *baudclk; | 174 | |
171 | struct clk *clk; | 175 | struct clk *clk; |
176 | struct clk *baudclk; | ||
177 | unsigned int baudclk_streams; | ||
178 | unsigned int bitclk_freq; | ||
179 | |||
180 | /* DMA params */ | ||
172 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 181 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
173 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 182 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
174 | struct imx_dma_data filter_data_tx; | 183 | dma_addr_t ssi_phys; |
175 | struct imx_dma_data filter_data_rx; | 184 | |
185 | /* params for non-dma FIQ stream filtered mode */ | ||
176 | struct imx_pcm_fiq_params fiq_params; | 186 | struct imx_pcm_fiq_params fiq_params; |
177 | /* Register values for rx/tx configuration */ | ||
178 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; | ||
179 | 187 | ||
180 | struct { | 188 | /* Used when using fsl-ssi as sound-card. This is only used by ppc and |
181 | unsigned int rfrc; | 189 | * should be replaced with simple-sound-card. */ |
182 | unsigned int tfrc; | 190 | struct platform_device *pdev; |
183 | unsigned int cmdau; | 191 | |
184 | unsigned int cmddu; | 192 | struct fsl_ssi_dbg dbg_stats; |
185 | unsigned int rxt; | 193 | |
186 | unsigned int rdr1; | 194 | const struct fsl_ssi_soc_data *soc; |
187 | unsigned int rdr0; | 195 | }; |
188 | unsigned int tde1; | 196 | |
189 | unsigned int tde0; | 197 | /* |
190 | unsigned int roe1; | 198 | * imx51 and later SoCs have a slightly different IP that allows the |
191 | unsigned int roe0; | 199 | * SSI configuration while the SSI unit is running. |
192 | unsigned int tue1; | 200 | * |
193 | unsigned int tue0; | 201 | * More important, it is necessary on those SoCs to configure the |
194 | unsigned int tfs; | 202 | * sperate TX/RX DMA bits just before starting the stream |
195 | unsigned int rfs; | 203 | * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi |
196 | unsigned int tls; | 204 | * sends any DMA requests to the SDMA unit, otherwise it is not defined |
197 | unsigned int rls; | 205 | * how the SDMA unit handles the DMA request. |
198 | unsigned int rff1; | 206 | * |
199 | unsigned int rff0; | 207 | * SDMA units are present on devices starting at imx35 but the imx35 |
200 | unsigned int tfe1; | 208 | * reference manual states that the DMA bits should not be changed |
201 | unsigned int tfe0; | 209 | * while the SSI unit is running (SSIEN). So we support the necessary |
202 | } stats; | 210 | * online configuration of fsl-ssi starting at imx51. |
203 | struct dentry *dbg_dir; | 211 | */ |
204 | struct dentry *dbg_stats; | 212 | |
205 | 213 | static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { | |
206 | char name[1]; | 214 | .imx = false, |
215 | .offline_config = true, | ||
216 | .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | ||
217 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
218 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | ||
219 | }; | ||
220 | |||
221 | static struct fsl_ssi_soc_data fsl_ssi_imx21 = { | ||
222 | .imx = true, | ||
223 | .offline_config = true, | ||
224 | .sisr_write_mask = 0, | ||
225 | }; | ||
226 | |||
227 | static struct fsl_ssi_soc_data fsl_ssi_imx35 = { | ||
228 | .imx = true, | ||
229 | .offline_config = true, | ||
230 | .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | ||
231 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
232 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | ||
233 | }; | ||
234 | |||
235 | static struct fsl_ssi_soc_data fsl_ssi_imx51 = { | ||
236 | .imx = true, | ||
237 | .offline_config = false, | ||
238 | .sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
239 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | ||
207 | }; | 240 | }; |
208 | 241 | ||
209 | static const struct of_device_id fsl_ssi_ids[] = { | 242 | static const struct of_device_id fsl_ssi_ids[] = { |
210 | { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610}, | 243 | { .compatible = "fsl,mpc8610-ssi", .data = &fsl_ssi_mpc8610 }, |
211 | { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51}, | 244 | { .compatible = "fsl,imx51-ssi", .data = &fsl_ssi_imx51 }, |
212 | { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35}, | 245 | { .compatible = "fsl,imx35-ssi", .data = &fsl_ssi_imx35 }, |
213 | { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21}, | 246 | { .compatible = "fsl,imx21-ssi", .data = &fsl_ssi_imx21 }, |
214 | {} | 247 | {} |
215 | }; | 248 | }; |
216 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | 249 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); |
217 | 250 | ||
251 | static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) | ||
252 | { | ||
253 | return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); | ||
254 | } | ||
255 | |||
256 | static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) | ||
257 | { | ||
258 | return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == | ||
259 | SND_SOC_DAIFMT_CBS_CFS; | ||
260 | } | ||
261 | |||
218 | /** | 262 | /** |
219 | * fsl_ssi_isr: SSI interrupt handler | 263 | * fsl_ssi_isr: SSI interrupt handler |
220 | * | 264 | * |
@@ -230,278 +274,98 @@ MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | |||
230 | static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | 274 | static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) |
231 | { | 275 | { |
232 | struct fsl_ssi_private *ssi_private = dev_id; | 276 | struct fsl_ssi_private *ssi_private = dev_id; |
233 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 277 | struct regmap *regs = ssi_private->regs; |
234 | irqreturn_t ret = IRQ_NONE; | ||
235 | __be32 sisr; | 278 | __be32 sisr; |
236 | __be32 sisr2; | 279 | __be32 sisr2; |
237 | __be32 sisr_write_mask = 0; | ||
238 | |||
239 | switch (ssi_private->hw_type) { | ||
240 | case FSL_SSI_MX21: | ||
241 | sisr_write_mask = 0; | ||
242 | break; | ||
243 | |||
244 | case FSL_SSI_MCP8610: | ||
245 | case FSL_SSI_MX35: | ||
246 | sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | ||
247 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
248 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
249 | break; | ||
250 | |||
251 | case FSL_SSI_MX51: | ||
252 | sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | ||
253 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1; | ||
254 | break; | ||
255 | } | ||
256 | 280 | ||
257 | /* We got an interrupt, so read the status register to see what we | 281 | /* We got an interrupt, so read the status register to see what we |
258 | were interrupted for. We mask it with the Interrupt Enable register | 282 | were interrupted for. We mask it with the Interrupt Enable register |
259 | so that we only check for events that we're interested in. | 283 | so that we only check for events that we're interested in. |
260 | */ | 284 | */ |
261 | sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK; | 285 | regmap_read(regs, CCSR_SSI_SISR, &sisr); |
262 | 286 | ||
263 | if (sisr & CCSR_SSI_SISR_RFRC) { | 287 | sisr2 = sisr & ssi_private->soc->sisr_write_mask; |
264 | ssi_private->stats.rfrc++; | ||
265 | ret = IRQ_HANDLED; | ||
266 | } | ||
267 | |||
268 | if (sisr & CCSR_SSI_SISR_TFRC) { | ||
269 | ssi_private->stats.tfrc++; | ||
270 | ret = IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | if (sisr & CCSR_SSI_SISR_CMDAU) { | ||
274 | ssi_private->stats.cmdau++; | ||
275 | ret = IRQ_HANDLED; | ||
276 | } | ||
277 | |||
278 | if (sisr & CCSR_SSI_SISR_CMDDU) { | ||
279 | ssi_private->stats.cmddu++; | ||
280 | ret = IRQ_HANDLED; | ||
281 | } | ||
282 | |||
283 | if (sisr & CCSR_SSI_SISR_RXT) { | ||
284 | ssi_private->stats.rxt++; | ||
285 | ret = IRQ_HANDLED; | ||
286 | } | ||
287 | |||
288 | if (sisr & CCSR_SSI_SISR_RDR1) { | ||
289 | ssi_private->stats.rdr1++; | ||
290 | ret = IRQ_HANDLED; | ||
291 | } | ||
292 | |||
293 | if (sisr & CCSR_SSI_SISR_RDR0) { | ||
294 | ssi_private->stats.rdr0++; | ||
295 | ret = IRQ_HANDLED; | ||
296 | } | ||
297 | |||
298 | if (sisr & CCSR_SSI_SISR_TDE1) { | ||
299 | ssi_private->stats.tde1++; | ||
300 | ret = IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | if (sisr & CCSR_SSI_SISR_TDE0) { | ||
304 | ssi_private->stats.tde0++; | ||
305 | ret = IRQ_HANDLED; | ||
306 | } | ||
307 | |||
308 | if (sisr & CCSR_SSI_SISR_ROE1) { | ||
309 | ssi_private->stats.roe1++; | ||
310 | ret = IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | if (sisr & CCSR_SSI_SISR_ROE0) { | ||
314 | ssi_private->stats.roe0++; | ||
315 | ret = IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | if (sisr & CCSR_SSI_SISR_TUE1) { | ||
319 | ssi_private->stats.tue1++; | ||
320 | ret = IRQ_HANDLED; | ||
321 | } | ||
322 | |||
323 | if (sisr & CCSR_SSI_SISR_TUE0) { | ||
324 | ssi_private->stats.tue0++; | ||
325 | ret = IRQ_HANDLED; | ||
326 | } | ||
327 | |||
328 | if (sisr & CCSR_SSI_SISR_TFS) { | ||
329 | ssi_private->stats.tfs++; | ||
330 | ret = IRQ_HANDLED; | ||
331 | } | ||
332 | |||
333 | if (sisr & CCSR_SSI_SISR_RFS) { | ||
334 | ssi_private->stats.rfs++; | ||
335 | ret = IRQ_HANDLED; | ||
336 | } | ||
337 | |||
338 | if (sisr & CCSR_SSI_SISR_TLS) { | ||
339 | ssi_private->stats.tls++; | ||
340 | ret = IRQ_HANDLED; | ||
341 | } | ||
342 | |||
343 | if (sisr & CCSR_SSI_SISR_RLS) { | ||
344 | ssi_private->stats.rls++; | ||
345 | ret = IRQ_HANDLED; | ||
346 | } | ||
347 | |||
348 | if (sisr & CCSR_SSI_SISR_RFF1) { | ||
349 | ssi_private->stats.rff1++; | ||
350 | ret = IRQ_HANDLED; | ||
351 | } | ||
352 | |||
353 | if (sisr & CCSR_SSI_SISR_RFF0) { | ||
354 | ssi_private->stats.rff0++; | ||
355 | ret = IRQ_HANDLED; | ||
356 | } | ||
357 | |||
358 | if (sisr & CCSR_SSI_SISR_TFE1) { | ||
359 | ssi_private->stats.tfe1++; | ||
360 | ret = IRQ_HANDLED; | ||
361 | } | ||
362 | |||
363 | if (sisr & CCSR_SSI_SISR_TFE0) { | ||
364 | ssi_private->stats.tfe0++; | ||
365 | ret = IRQ_HANDLED; | ||
366 | } | ||
367 | |||
368 | sisr2 = sisr & sisr_write_mask; | ||
369 | /* Clear the bits that we set */ | 288 | /* Clear the bits that we set */ |
370 | if (sisr2) | 289 | if (sisr2) |
371 | write_ssi(sisr2, &ssi->sisr); | 290 | regmap_write(regs, CCSR_SSI_SISR, sisr2); |
372 | |||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
377 | /* Show the statistics of a flag only if its interrupt is enabled. The | ||
378 | * compiler will optimze this code to a no-op if the interrupt is not | ||
379 | * enabled. | ||
380 | */ | ||
381 | #define SIER_SHOW(flag, name) \ | ||
382 | do { \ | ||
383 | if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \ | ||
384 | seq_printf(s, #name "=%u\n", ssi_private->stats.name); \ | ||
385 | } while (0) | ||
386 | |||
387 | |||
388 | /** | ||
389 | * fsl_sysfs_ssi_show: display SSI statistics | ||
390 | * | ||
391 | * Display the statistics for the current SSI device. To avoid confusion, | ||
392 | * we only show those counts that are enabled. | ||
393 | */ | ||
394 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | ||
395 | { | ||
396 | struct fsl_ssi_private *ssi_private = s->private; | ||
397 | |||
398 | SIER_SHOW(RFRC_EN, rfrc); | ||
399 | SIER_SHOW(TFRC_EN, tfrc); | ||
400 | SIER_SHOW(CMDAU_EN, cmdau); | ||
401 | SIER_SHOW(CMDDU_EN, cmddu); | ||
402 | SIER_SHOW(RXT_EN, rxt); | ||
403 | SIER_SHOW(RDR1_EN, rdr1); | ||
404 | SIER_SHOW(RDR0_EN, rdr0); | ||
405 | SIER_SHOW(TDE1_EN, tde1); | ||
406 | SIER_SHOW(TDE0_EN, tde0); | ||
407 | SIER_SHOW(ROE1_EN, roe1); | ||
408 | SIER_SHOW(ROE0_EN, roe0); | ||
409 | SIER_SHOW(TUE1_EN, tue1); | ||
410 | SIER_SHOW(TUE0_EN, tue0); | ||
411 | SIER_SHOW(TFS_EN, tfs); | ||
412 | SIER_SHOW(RFS_EN, rfs); | ||
413 | SIER_SHOW(TLS_EN, tls); | ||
414 | SIER_SHOW(RLS_EN, rls); | ||
415 | SIER_SHOW(RFF1_EN, rff1); | ||
416 | SIER_SHOW(RFF0_EN, rff0); | ||
417 | SIER_SHOW(TFE1_EN, tfe1); | ||
418 | SIER_SHOW(TFE0_EN, tfe0); | ||
419 | |||
420 | return 0; | ||
421 | } | ||
422 | |||
423 | static int fsl_ssi_stats_open(struct inode *inode, struct file *file) | ||
424 | { | ||
425 | return single_open(file, fsl_ssi_stats_show, inode->i_private); | ||
426 | } | ||
427 | |||
428 | static const struct file_operations fsl_ssi_stats_ops = { | ||
429 | .open = fsl_ssi_stats_open, | ||
430 | .read = seq_read, | ||
431 | .llseek = seq_lseek, | ||
432 | .release = single_release, | ||
433 | }; | ||
434 | |||
435 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
436 | struct device *dev) | ||
437 | { | ||
438 | ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); | ||
439 | if (!ssi_private->dbg_dir) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO, | ||
443 | ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops); | ||
444 | if (!ssi_private->dbg_stats) { | ||
445 | debugfs_remove(ssi_private->dbg_dir); | ||
446 | return -ENOMEM; | ||
447 | } | ||
448 | 291 | ||
449 | return 0; | 292 | fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr); |
450 | } | ||
451 | |||
452 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | ||
453 | { | ||
454 | debugfs_remove(ssi_private->dbg_stats); | ||
455 | debugfs_remove(ssi_private->dbg_dir); | ||
456 | } | ||
457 | 293 | ||
458 | #else | 294 | return IRQ_HANDLED; |
459 | |||
460 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
461 | struct device *dev) | ||
462 | { | ||
463 | return 0; | ||
464 | } | 295 | } |
465 | 296 | ||
466 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | ||
467 | { | ||
468 | } | ||
469 | |||
470 | #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ | ||
471 | |||
472 | /* | 297 | /* |
473 | * Enable/Disable all rx/tx config flags at once. | 298 | * Enable/Disable all rx/tx config flags at once. |
474 | */ | 299 | */ |
475 | static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, | 300 | static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, |
476 | bool enable) | 301 | bool enable) |
477 | { | 302 | { |
478 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 303 | struct regmap *regs = ssi_private->regs; |
479 | struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val; | 304 | struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val; |
480 | 305 | ||
481 | if (enable) { | 306 | if (enable) { |
482 | write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier); | 307 | regmap_update_bits(regs, CCSR_SSI_SIER, |
483 | write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr); | 308 | vals->rx.sier | vals->tx.sier, |
484 | write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr); | 309 | vals->rx.sier | vals->tx.sier); |
310 | regmap_update_bits(regs, CCSR_SSI_SRCR, | ||
311 | vals->rx.srcr | vals->tx.srcr, | ||
312 | vals->rx.srcr | vals->tx.srcr); | ||
313 | regmap_update_bits(regs, CCSR_SSI_STCR, | ||
314 | vals->rx.stcr | vals->tx.stcr, | ||
315 | vals->rx.stcr | vals->tx.stcr); | ||
485 | } else { | 316 | } else { |
486 | write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0); | 317 | regmap_update_bits(regs, CCSR_SSI_SRCR, |
487 | write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0); | 318 | vals->rx.srcr | vals->tx.srcr, 0); |
488 | write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0); | 319 | regmap_update_bits(regs, CCSR_SSI_STCR, |
320 | vals->rx.stcr | vals->tx.stcr, 0); | ||
321 | regmap_update_bits(regs, CCSR_SSI_SIER, | ||
322 | vals->rx.sier | vals->tx.sier, 0); | ||
489 | } | 323 | } |
490 | } | 324 | } |
491 | 325 | ||
492 | /* | 326 | /* |
327 | * Calculate the bits that have to be disabled for the current stream that is | ||
328 | * getting disabled. This keeps the bits enabled that are necessary for the | ||
329 | * second stream to work if 'stream_active' is true. | ||
330 | * | ||
331 | * Detailed calculation: | ||
332 | * These are the values that need to be active after disabling. For non-active | ||
333 | * second stream, this is 0: | ||
334 | * vals_stream * !!stream_active | ||
335 | * | ||
336 | * The following computes the overall differences between the setup for the | ||
337 | * to-disable stream and the active stream, a simple XOR: | ||
338 | * vals_disable ^ (vals_stream * !!(stream_active)) | ||
339 | * | ||
340 | * The full expression adds a mask on all values we care about | ||
341 | */ | ||
342 | #define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \ | ||
343 | ((vals_disable) & \ | ||
344 | ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active)))) | ||
345 | |||
346 | /* | ||
493 | * Enable/Disable a ssi configuration. You have to pass either | 347 | * Enable/Disable a ssi configuration. You have to pass either |
494 | * ssi_private->rxtx_reg_val.rx or tx as vals parameter. | 348 | * ssi_private->rxtx_reg_val.rx or tx as vals parameter. |
495 | */ | 349 | */ |
496 | static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | 350 | static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, |
497 | struct fsl_ssi_reg_val *vals) | 351 | struct fsl_ssi_reg_val *vals) |
498 | { | 352 | { |
499 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 353 | struct regmap *regs = ssi_private->regs; |
500 | struct fsl_ssi_reg_val *avals; | 354 | struct fsl_ssi_reg_val *avals; |
501 | u32 scr_val = read_ssi(&ssi->scr); | 355 | int nr_active_streams; |
502 | int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + | 356 | u32 scr_val; |
357 | int keep_active; | ||
358 | |||
359 | regmap_read(regs, CCSR_SSI_SCR, &scr_val); | ||
360 | |||
361 | nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + | ||
503 | !!(scr_val & CCSR_SSI_SCR_RE); | 362 | !!(scr_val & CCSR_SSI_SCR_RE); |
504 | 363 | ||
364 | if (nr_active_streams - 1 > 0) | ||
365 | keep_active = 1; | ||
366 | else | ||
367 | keep_active = 0; | ||
368 | |||
505 | /* Find the other direction values rx or tx which we do not want to | 369 | /* Find the other direction values rx or tx which we do not want to |
506 | * modify */ | 370 | * modify */ |
507 | if (&ssi_private->rxtx_reg_val.rx == vals) | 371 | if (&ssi_private->rxtx_reg_val.rx == vals) |
@@ -511,8 +375,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
511 | 375 | ||
512 | /* If vals should be disabled, start with disabling the unit */ | 376 | /* If vals should be disabled, start with disabling the unit */ |
513 | if (!enable) { | 377 | if (!enable) { |
514 | u32 scr = vals->scr & (vals->scr ^ avals->scr); | 378 | u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, |
515 | write_ssi_mask(&ssi->scr, scr, 0); | 379 | keep_active); |
380 | regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0); | ||
516 | } | 381 | } |
517 | 382 | ||
518 | /* | 383 | /* |
@@ -520,9 +385,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
520 | * reconfiguration, so we have to enable all necessary flags at once | 385 | * reconfiguration, so we have to enable all necessary flags at once |
521 | * even if we do not use them later (capture and playback configuration) | 386 | * even if we do not use them later (capture and playback configuration) |
522 | */ | 387 | */ |
523 | if (ssi_private->offline_config) { | 388 | if (ssi_private->soc->offline_config) { |
524 | if ((enable && !nr_active_streams) || | 389 | if ((enable && !nr_active_streams) || |
525 | (!enable && nr_active_streams == 1)) | 390 | (!enable && !keep_active)) |
526 | fsl_ssi_rxtx_config(ssi_private, enable); | 391 | fsl_ssi_rxtx_config(ssi_private, enable); |
527 | 392 | ||
528 | goto config_done; | 393 | goto config_done; |
@@ -533,9 +398,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
533 | * (online configuration) | 398 | * (online configuration) |
534 | */ | 399 | */ |
535 | if (enable) { | 400 | if (enable) { |
536 | write_ssi_mask(&ssi->sier, 0, vals->sier); | 401 | regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier); |
537 | write_ssi_mask(&ssi->srcr, 0, vals->srcr); | 402 | regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr); |
538 | write_ssi_mask(&ssi->stcr, 0, vals->stcr); | 403 | regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr); |
539 | } else { | 404 | } else { |
540 | u32 sier; | 405 | u32 sier; |
541 | u32 srcr; | 406 | u32 srcr; |
@@ -551,19 +416,22 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
551 | */ | 416 | */ |
552 | 417 | ||
553 | /* These assignments are simply vals without bits set in avals*/ | 418 | /* These assignments are simply vals without bits set in avals*/ |
554 | sier = vals->sier & (vals->sier ^ avals->sier); | 419 | sier = fsl_ssi_disable_val(vals->sier, avals->sier, |
555 | srcr = vals->srcr & (vals->srcr ^ avals->srcr); | 420 | keep_active); |
556 | stcr = vals->stcr & (vals->stcr ^ avals->stcr); | 421 | srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr, |
557 | 422 | keep_active); | |
558 | write_ssi_mask(&ssi->srcr, srcr, 0); | 423 | stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, |
559 | write_ssi_mask(&ssi->stcr, stcr, 0); | 424 | keep_active); |
560 | write_ssi_mask(&ssi->sier, sier, 0); | 425 | |
426 | regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0); | ||
427 | regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0); | ||
428 | regmap_update_bits(regs, CCSR_SSI_SIER, sier, 0); | ||
561 | } | 429 | } |
562 | 430 | ||
563 | config_done: | 431 | config_done: |
564 | /* Enabling of subunits is done after configuration */ | 432 | /* Enabling of subunits is done after configuration */ |
565 | if (enable) | 433 | if (enable) |
566 | write_ssi_mask(&ssi->scr, 0, vals->scr); | 434 | regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr); |
567 | } | 435 | } |
568 | 436 | ||
569 | 437 | ||
@@ -593,7 +461,7 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) | |||
593 | reg->tx.stcr = CCSR_SSI_STCR_TFEN0; | 461 | reg->tx.stcr = CCSR_SSI_STCR_TFEN0; |
594 | reg->tx.scr = 0; | 462 | reg->tx.scr = 0; |
595 | 463 | ||
596 | if (!ssi_private->imx_ac97) { | 464 | if (!fsl_ssi_is_ac97(ssi_private)) { |
597 | reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; | 465 | reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; |
598 | reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; | 466 | reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; |
599 | reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; | 467 | reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; |
@@ -614,124 +482,35 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) | |||
614 | 482 | ||
615 | static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) | 483 | static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) |
616 | { | 484 | { |
617 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 485 | struct regmap *regs = ssi_private->regs; |
618 | 486 | ||
619 | /* | 487 | /* |
620 | * Setup the clock control register | 488 | * Setup the clock control register |
621 | */ | 489 | */ |
622 | write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), | 490 | regmap_write(regs, CCSR_SSI_STCCR, |
623 | &ssi->stccr); | 491 | CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); |
624 | write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13), | 492 | regmap_write(regs, CCSR_SSI_SRCCR, |
625 | &ssi->srccr); | 493 | CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); |
626 | 494 | ||
627 | /* | 495 | /* |
628 | * Enable AC97 mode and startup the SSI | 496 | * Enable AC97 mode and startup the SSI |
629 | */ | 497 | */ |
630 | write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV, | 498 | regmap_write(regs, CCSR_SSI_SACNT, |
631 | &ssi->sacnt); | 499 | CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV); |
632 | write_ssi(0xff, &ssi->saccdis); | 500 | regmap_write(regs, CCSR_SSI_SACCDIS, 0xff); |
633 | write_ssi(0x300, &ssi->saccen); | 501 | regmap_write(regs, CCSR_SSI_SACCEN, 0x300); |
634 | 502 | ||
635 | /* | 503 | /* |
636 | * Enable SSI, Transmit and Receive. AC97 has to communicate with the | 504 | * Enable SSI, Transmit and Receive. AC97 has to communicate with the |
637 | * codec before a stream is started. | 505 | * codec before a stream is started. |
638 | */ | 506 | */ |
639 | write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN | | 507 | regmap_update_bits(regs, CCSR_SSI_SCR, |
640 | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); | 508 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE, |
509 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); | ||
641 | 510 | ||
642 | write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); | 511 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_WAIT(3)); |
643 | } | 512 | } |
644 | 513 | ||
645 | static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) | ||
646 | { | ||
647 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
648 | u8 wm; | ||
649 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; | ||
650 | |||
651 | fsl_ssi_setup_reg_vals(ssi_private); | ||
652 | |||
653 | if (ssi_private->imx_ac97) | ||
654 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; | ||
655 | else | ||
656 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; | ||
657 | |||
658 | /* | ||
659 | * Section 16.5 of the MPC8610 reference manual says that the SSI needs | ||
660 | * to be disabled before updating the registers we set here. | ||
661 | */ | ||
662 | write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); | ||
663 | |||
664 | /* | ||
665 | * Program the SSI into I2S Slave Non-Network Synchronous mode. Also | ||
666 | * enable the transmit and receive FIFO. | ||
667 | * | ||
668 | * FIXME: Little-endian samples require a different shift dir | ||
669 | */ | ||
670 | write_ssi_mask(&ssi->scr, | ||
671 | CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, | ||
672 | CCSR_SSI_SCR_TFR_CLK_DIS | | ||
673 | ssi_private->i2s_mode | | ||
674 | (synchronous ? CCSR_SSI_SCR_SYN : 0)); | ||
675 | |||
676 | write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI | | ||
677 | CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr); | ||
678 | |||
679 | write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI | | ||
680 | CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr); | ||
681 | |||
682 | /* | ||
683 | * The DC and PM bits are only used if the SSI is the clock master. | ||
684 | */ | ||
685 | |||
686 | /* | ||
687 | * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't | ||
688 | * use FIFO 1. We program the transmit water to signal a DMA transfer | ||
689 | * if there are only two (or fewer) elements left in the FIFO. Two | ||
690 | * elements equals one frame (left channel, right channel). This value, | ||
691 | * however, depends on the depth of the transmit buffer. | ||
692 | * | ||
693 | * We set the watermark on the same level as the DMA burstsize. For | ||
694 | * fiq it is probably better to use the biggest possible watermark | ||
695 | * size. | ||
696 | */ | ||
697 | if (ssi_private->use_dma) | ||
698 | wm = ssi_private->fifo_depth - 2; | ||
699 | else | ||
700 | wm = ssi_private->fifo_depth; | ||
701 | |||
702 | write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | | ||
703 | CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), | ||
704 | &ssi->sfcsr); | ||
705 | |||
706 | /* | ||
707 | * For ac97 interrupts are enabled with the startup of the substream | ||
708 | * because it is also running without an active substream. Normally SSI | ||
709 | * is only enabled when there is a substream. | ||
710 | */ | ||
711 | if (ssi_private->imx_ac97) | ||
712 | fsl_ssi_setup_ac97(ssi_private); | ||
713 | |||
714 | /* | ||
715 | * Set a default slot number so that there is no need for those common | ||
716 | * cases like I2S mode to call the extra set_tdm_slot() any more. | ||
717 | */ | ||
718 | if (!ssi_private->imx_ac97) { | ||
719 | write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, | ||
720 | CCSR_SSI_SxCCR_DC(2)); | ||
721 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, | ||
722 | CCSR_SSI_SxCCR_DC(2)); | ||
723 | } | ||
724 | |||
725 | if (ssi_private->use_dual_fifo) { | ||
726 | write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); | ||
727 | write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); | ||
728 | write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); | ||
729 | } | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | |||
735 | /** | 514 | /** |
736 | * fsl_ssi_startup: create a new substream | 515 | * fsl_ssi_startup: create a new substream |
737 | * | 516 | * |
@@ -746,18 +525,6 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
746 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 525 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
747 | struct fsl_ssi_private *ssi_private = | 526 | struct fsl_ssi_private *ssi_private = |
748 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | 527 | snd_soc_dai_get_drvdata(rtd->cpu_dai); |
749 | unsigned long flags; | ||
750 | |||
751 | /* First, we only do fsl_ssi_setup() when SSI is going to be active. | ||
752 | * Second, fsl_ssi_setup was already called by ac97_init earlier if | ||
753 | * the driver is in ac97 mode. | ||
754 | */ | ||
755 | if (!dai->active && !ssi_private->imx_ac97) { | ||
756 | fsl_ssi_setup(ssi_private); | ||
757 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | ||
758 | ssi_private->baudclk_locked = false; | ||
759 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
760 | } | ||
761 | 528 | ||
762 | /* When using dual fifo mode, it is safer to ensure an even period | 529 | /* When using dual fifo mode, it is safer to ensure an even period |
763 | * size. If appearing to an odd number while DMA always starts its | 530 | * size. If appearing to an odd number while DMA always starts its |
@@ -772,6 +539,122 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
772 | } | 539 | } |
773 | 540 | ||
774 | /** | 541 | /** |
542 | * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock | ||
543 | * | ||
544 | * Note: This function can be only called when using SSI as DAI master | ||
545 | * | ||
546 | * Quick instruction for parameters: | ||
547 | * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels | ||
548 | * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. | ||
549 | */ | ||
550 | static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | ||
551 | struct snd_soc_dai *cpu_dai, | ||
552 | struct snd_pcm_hw_params *hw_params) | ||
553 | { | ||
554 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | ||
555 | struct regmap *regs = ssi_private->regs; | ||
556 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; | ||
557 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; | ||
558 | unsigned long clkrate, baudrate, tmprate; | ||
559 | u64 sub, savesub = 100000; | ||
560 | unsigned int freq; | ||
561 | bool baudclk_is_used; | ||
562 | |||
563 | /* Prefer the explicitly set bitclock frequency */ | ||
564 | if (ssi_private->bitclk_freq) | ||
565 | freq = ssi_private->bitclk_freq; | ||
566 | else | ||
567 | freq = params_channels(hw_params) * 32 * params_rate(hw_params); | ||
568 | |||
569 | /* Don't apply it to any non-baudclk circumstance */ | ||
570 | if (IS_ERR(ssi_private->baudclk)) | ||
571 | return -EINVAL; | ||
572 | |||
573 | baudclk_is_used = ssi_private->baudclk_streams & ~(BIT(substream->stream)); | ||
574 | |||
575 | /* It should be already enough to divide clock by setting pm alone */ | ||
576 | psr = 0; | ||
577 | div2 = 0; | ||
578 | |||
579 | factor = (div2 + 1) * (7 * psr + 1) * 2; | ||
580 | |||
581 | for (i = 0; i < 255; i++) { | ||
582 | /* The bclk rate must be smaller than 1/5 sysclk rate */ | ||
583 | if (factor * (i + 1) < 5) | ||
584 | continue; | ||
585 | |||
586 | tmprate = freq * factor * (i + 2); | ||
587 | |||
588 | if (baudclk_is_used) | ||
589 | clkrate = clk_get_rate(ssi_private->baudclk); | ||
590 | else | ||
591 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); | ||
592 | |||
593 | do_div(clkrate, factor); | ||
594 | afreq = (u32)clkrate / (i + 1); | ||
595 | |||
596 | if (freq == afreq) | ||
597 | sub = 0; | ||
598 | else if (freq / afreq == 1) | ||
599 | sub = freq - afreq; | ||
600 | else if (afreq / freq == 1) | ||
601 | sub = afreq - freq; | ||
602 | else | ||
603 | continue; | ||
604 | |||
605 | /* Calculate the fraction */ | ||
606 | sub *= 100000; | ||
607 | do_div(sub, freq); | ||
608 | |||
609 | if (sub < savesub) { | ||
610 | baudrate = tmprate; | ||
611 | savesub = sub; | ||
612 | pm = i; | ||
613 | } | ||
614 | |||
615 | /* We are lucky */ | ||
616 | if (savesub == 0) | ||
617 | break; | ||
618 | } | ||
619 | |||
620 | /* No proper pm found if it is still remaining the initial value */ | ||
621 | if (pm == 999) { | ||
622 | dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); | ||
623 | return -EINVAL; | ||
624 | } | ||
625 | |||
626 | stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | | ||
627 | (psr ? CCSR_SSI_SxCCR_PSR : 0); | ||
628 | mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | | ||
629 | CCSR_SSI_SxCCR_PSR; | ||
630 | |||
631 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous) | ||
632 | regmap_update_bits(regs, CCSR_SSI_STCCR, mask, stccr); | ||
633 | else | ||
634 | regmap_update_bits(regs, CCSR_SSI_SRCCR, mask, stccr); | ||
635 | |||
636 | if (!baudclk_is_used) { | ||
637 | ret = clk_set_rate(ssi_private->baudclk, baudrate); | ||
638 | if (ret) { | ||
639 | dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); | ||
640 | return -EINVAL; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | ||
648 | int clk_id, unsigned int freq, int dir) | ||
649 | { | ||
650 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | ||
651 | |||
652 | ssi_private->bitclk_freq = freq; | ||
653 | |||
654 | return 0; | ||
655 | } | ||
656 | |||
657 | /** | ||
775 | * fsl_ssi_hw_params - program the sample size | 658 | * fsl_ssi_hw_params - program the sample size |
776 | * | 659 | * |
777 | * Most of the SSI registers have been programmed in the startup function, | 660 | * Most of the SSI registers have been programmed in the startup function, |
@@ -788,12 +671,17 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
788 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) | 671 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) |
789 | { | 672 | { |
790 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 673 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
791 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 674 | struct regmap *regs = ssi_private->regs; |
792 | unsigned int channels = params_channels(hw_params); | 675 | unsigned int channels = params_channels(hw_params); |
793 | unsigned int sample_size = | 676 | unsigned int sample_size = |
794 | snd_pcm_format_width(params_format(hw_params)); | 677 | snd_pcm_format_width(params_format(hw_params)); |
795 | u32 wl = CCSR_SSI_SxCCR_WL(sample_size); | 678 | u32 wl = CCSR_SSI_SxCCR_WL(sample_size); |
796 | int enabled = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; | 679 | int ret; |
680 | u32 scr_val; | ||
681 | int enabled; | ||
682 | |||
683 | regmap_read(regs, CCSR_SSI_SCR, &scr_val); | ||
684 | enabled = scr_val & CCSR_SSI_SCR_SSIEN; | ||
797 | 685 | ||
798 | /* | 686 | /* |
799 | * If we're in synchronous mode, and the SSI is already enabled, | 687 | * If we're in synchronous mode, and the SSI is already enabled, |
@@ -802,6 +690,21 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
802 | if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) | 690 | if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) |
803 | return 0; | 691 | return 0; |
804 | 692 | ||
693 | if (fsl_ssi_is_i2s_master(ssi_private)) { | ||
694 | ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params); | ||
695 | if (ret) | ||
696 | return ret; | ||
697 | |||
698 | /* Do not enable the clock if it is already enabled */ | ||
699 | if (!(ssi_private->baudclk_streams & BIT(substream->stream))) { | ||
700 | ret = clk_prepare_enable(ssi_private->baudclk); | ||
701 | if (ret) | ||
702 | return ret; | ||
703 | |||
704 | ssi_private->baudclk_streams |= BIT(substream->stream); | ||
705 | } | ||
706 | } | ||
707 | |||
805 | /* | 708 | /* |
806 | * FIXME: The documentation says that SxCCR[WL] should not be | 709 | * FIXME: The documentation says that SxCCR[WL] should not be |
807 | * modified while the SSI is enabled. The only time this can | 710 | * modified while the SSI is enabled. The only time this can |
@@ -815,49 +718,83 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
815 | /* In synchronous mode, the SSI uses STCCR for capture */ | 718 | /* In synchronous mode, the SSI uses STCCR for capture */ |
816 | if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || | 719 | if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || |
817 | ssi_private->cpu_dai_drv.symmetric_rates) | 720 | ssi_private->cpu_dai_drv.symmetric_rates) |
818 | write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); | 721 | regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK, |
722 | wl); | ||
819 | else | 723 | else |
820 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); | 724 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, |
725 | wl); | ||
821 | 726 | ||
822 | if (!ssi_private->imx_ac97) | 727 | if (!fsl_ssi_is_ac97(ssi_private)) |
823 | write_ssi_mask(&ssi->scr, | 728 | regmap_update_bits(regs, CCSR_SSI_SCR, |
824 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, | 729 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, |
825 | channels == 1 ? 0 : ssi_private->i2s_mode); | 730 | channels == 1 ? 0 : ssi_private->i2s_mode); |
826 | 731 | ||
827 | return 0; | 732 | return 0; |
828 | } | 733 | } |
829 | 734 | ||
830 | /** | 735 | static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, |
831 | * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. | 736 | struct snd_soc_dai *cpu_dai) |
832 | */ | ||
833 | static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | ||
834 | { | 737 | { |
835 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 738 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
836 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 739 | struct fsl_ssi_private *ssi_private = |
740 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
741 | |||
742 | if (fsl_ssi_is_i2s_master(ssi_private) && | ||
743 | ssi_private->baudclk_streams & BIT(substream->stream)) { | ||
744 | clk_disable_unprepare(ssi_private->baudclk); | ||
745 | ssi_private->baudclk_streams &= ~BIT(substream->stream); | ||
746 | } | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, | ||
752 | unsigned int fmt) | ||
753 | { | ||
754 | struct regmap *regs = ssi_private->regs; | ||
837 | u32 strcr = 0, stcr, srcr, scr, mask; | 755 | u32 strcr = 0, stcr, srcr, scr, mask; |
756 | u8 wm; | ||
838 | 757 | ||
839 | scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); | 758 | ssi_private->dai_fmt = fmt; |
840 | scr |= CCSR_SSI_SCR_NET; | 759 | |
760 | if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) { | ||
761 | dev_err(&ssi_private->pdev->dev, "baudclk is missing which is necessary for master mode\n"); | ||
762 | return -EINVAL; | ||
763 | } | ||
764 | |||
765 | fsl_ssi_setup_reg_vals(ssi_private); | ||
766 | |||
767 | regmap_read(regs, CCSR_SSI_SCR, &scr); | ||
768 | scr &= ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); | ||
769 | scr |= CCSR_SSI_SCR_SYNC_TX_FS; | ||
841 | 770 | ||
842 | mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | | 771 | mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | |
843 | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | | 772 | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | |
844 | CCSR_SSI_STCR_TEFS; | 773 | CCSR_SSI_STCR_TEFS; |
845 | stcr = read_ssi(&ssi->stcr) & ~mask; | 774 | regmap_read(regs, CCSR_SSI_STCR, &stcr); |
846 | srcr = read_ssi(&ssi->srcr) & ~mask; | 775 | regmap_read(regs, CCSR_SSI_SRCR, &srcr); |
776 | stcr &= ~mask; | ||
777 | srcr &= ~mask; | ||
847 | 778 | ||
779 | ssi_private->i2s_mode = CCSR_SSI_SCR_NET; | ||
848 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 780 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
849 | case SND_SOC_DAIFMT_I2S: | 781 | case SND_SOC_DAIFMT_I2S: |
850 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 782 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
851 | case SND_SOC_DAIFMT_CBS_CFS: | 783 | case SND_SOC_DAIFMT_CBS_CFS: |
852 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER; | 784 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; |
785 | regmap_update_bits(regs, CCSR_SSI_STCCR, | ||
786 | CCSR_SSI_SxCCR_DC_MASK, | ||
787 | CCSR_SSI_SxCCR_DC(2)); | ||
788 | regmap_update_bits(regs, CCSR_SSI_SRCCR, | ||
789 | CCSR_SSI_SxCCR_DC_MASK, | ||
790 | CCSR_SSI_SxCCR_DC(2)); | ||
853 | break; | 791 | break; |
854 | case SND_SOC_DAIFMT_CBM_CFM: | 792 | case SND_SOC_DAIFMT_CBM_CFM: |
855 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; | 793 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; |
856 | break; | 794 | break; |
857 | default: | 795 | default: |
858 | return -EINVAL; | 796 | return -EINVAL; |
859 | } | 797 | } |
860 | scr |= ssi_private->i2s_mode; | ||
861 | 798 | ||
862 | /* Data on rising edge of bclk, frame low, 1clk before data */ | 799 | /* Data on rising edge of bclk, frame low, 1clk before data */ |
863 | strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | | 800 | strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | |
@@ -877,9 +814,13 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
877 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | | 814 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | |
878 | CCSR_SSI_STCR_TXBIT0; | 815 | CCSR_SSI_STCR_TXBIT0; |
879 | break; | 816 | break; |
817 | case SND_SOC_DAIFMT_AC97: | ||
818 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL; | ||
819 | break; | ||
880 | default: | 820 | default: |
881 | return -EINVAL; | 821 | return -EINVAL; |
882 | } | 822 | } |
823 | scr |= ssi_private->i2s_mode; | ||
883 | 824 | ||
884 | /* DAI clock inversion */ | 825 | /* DAI clock inversion */ |
885 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 826 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -925,105 +866,54 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
925 | scr |= CCSR_SSI_SCR_SYN; | 866 | scr |= CCSR_SSI_SCR_SYN; |
926 | } | 867 | } |
927 | 868 | ||
928 | write_ssi(stcr, &ssi->stcr); | 869 | regmap_write(regs, CCSR_SSI_STCR, stcr); |
929 | write_ssi(srcr, &ssi->srcr); | 870 | regmap_write(regs, CCSR_SSI_SRCR, srcr); |
930 | write_ssi(scr, &ssi->scr); | 871 | regmap_write(regs, CCSR_SSI_SCR, scr); |
931 | |||
932 | return 0; | ||
933 | } | ||
934 | 872 | ||
935 | /** | 873 | /* |
936 | * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock | 874 | * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't |
937 | * | 875 | * use FIFO 1. We program the transmit water to signal a DMA transfer |
938 | * Note: This function can be only called when using SSI as DAI master | 876 | * if there are only two (or fewer) elements left in the FIFO. Two |
939 | * | 877 | * elements equals one frame (left channel, right channel). This value, |
940 | * Quick instruction for parameters: | 878 | * however, depends on the depth of the transmit buffer. |
941 | * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels | 879 | * |
942 | * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. | 880 | * We set the watermark on the same level as the DMA burstsize. For |
943 | */ | 881 | * fiq it is probably better to use the biggest possible watermark |
944 | static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | 882 | * size. |
945 | int clk_id, unsigned int freq, int dir) | 883 | */ |
946 | { | 884 | if (ssi_private->use_dma) |
947 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 885 | wm = ssi_private->fifo_depth - 2; |
948 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 886 | else |
949 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; | 887 | wm = ssi_private->fifo_depth; |
950 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; | ||
951 | unsigned long flags, clkrate, baudrate, tmprate; | ||
952 | u64 sub, savesub = 100000; | ||
953 | |||
954 | /* Don't apply it to any non-baudclk circumstance */ | ||
955 | if (IS_ERR(ssi_private->baudclk)) | ||
956 | return -EINVAL; | ||
957 | |||
958 | /* It should be already enough to divide clock by setting pm alone */ | ||
959 | psr = 0; | ||
960 | div2 = 0; | ||
961 | |||
962 | factor = (div2 + 1) * (7 * psr + 1) * 2; | ||
963 | |||
964 | for (i = 0; i < 255; i++) { | ||
965 | /* The bclk rate must be smaller than 1/5 sysclk rate */ | ||
966 | if (factor * (i + 1) < 5) | ||
967 | continue; | ||
968 | |||
969 | tmprate = freq * factor * (i + 2); | ||
970 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); | ||
971 | |||
972 | do_div(clkrate, factor); | ||
973 | afreq = (u32)clkrate / (i + 1); | ||
974 | |||
975 | if (freq == afreq) | ||
976 | sub = 0; | ||
977 | else if (freq / afreq == 1) | ||
978 | sub = freq - afreq; | ||
979 | else if (afreq / freq == 1) | ||
980 | sub = afreq - freq; | ||
981 | else | ||
982 | continue; | ||
983 | |||
984 | /* Calculate the fraction */ | ||
985 | sub *= 100000; | ||
986 | do_div(sub, freq); | ||
987 | 888 | ||
988 | if (sub < savesub) { | 889 | regmap_write(regs, CCSR_SSI_SFCSR, |
989 | baudrate = tmprate; | 890 | CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | |
990 | savesub = sub; | 891 | CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm)); |
991 | pm = i; | ||
992 | } | ||
993 | 892 | ||
994 | /* We are lucky */ | 893 | if (ssi_private->use_dual_fifo) { |
995 | if (savesub == 0) | 894 | regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1, |
996 | break; | 895 | CCSR_SSI_SRCR_RFEN1); |
896 | regmap_update_bits(regs, CCSR_SSI_STCR, CCSR_SSI_STCR_TFEN1, | ||
897 | CCSR_SSI_STCR_TFEN1); | ||
898 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_TCH_EN, | ||
899 | CCSR_SSI_SCR_TCH_EN); | ||
997 | } | 900 | } |
998 | 901 | ||
999 | /* No proper pm found if it is still remaining the initial value */ | 902 | if (fmt & SND_SOC_DAIFMT_AC97) |
1000 | if (pm == 999) { | 903 | fsl_ssi_setup_ac97(ssi_private); |
1001 | dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); | ||
1002 | return -EINVAL; | ||
1003 | } | ||
1004 | 904 | ||
1005 | stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | | 905 | return 0; |
1006 | (psr ? CCSR_SSI_SxCCR_PSR : 0); | ||
1007 | mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR; | ||
1008 | 906 | ||
1009 | if (dir == SND_SOC_CLOCK_OUT || synchronous) | 907 | } |
1010 | write_ssi_mask(&ssi->stccr, mask, stccr); | ||
1011 | else | ||
1012 | write_ssi_mask(&ssi->srccr, mask, stccr); | ||
1013 | 908 | ||
1014 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | 909 | /** |
1015 | if (!ssi_private->baudclk_locked) { | 910 | * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. |
1016 | ret = clk_set_rate(ssi_private->baudclk, baudrate); | 911 | */ |
1017 | if (ret) { | 912 | static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) |
1018 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | 913 | { |
1019 | dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); | 914 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
1020 | return -EINVAL; | ||
1021 | } | ||
1022 | ssi_private->baudclk_locked = true; | ||
1023 | } | ||
1024 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
1025 | 915 | ||
1026 | return 0; | 916 | return _fsl_ssi_set_dai_fmt(ssi_private, fmt); |
1027 | } | 917 | } |
1028 | 918 | ||
1029 | /** | 919 | /** |
@@ -1035,31 +925,34 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, | |||
1035 | u32 rx_mask, int slots, int slot_width) | 925 | u32 rx_mask, int slots, int slot_width) |
1036 | { | 926 | { |
1037 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 927 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
1038 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 928 | struct regmap *regs = ssi_private->regs; |
1039 | u32 val; | 929 | u32 val; |
1040 | 930 | ||
1041 | /* The slot number should be >= 2 if using Network mode or I2S mode */ | 931 | /* The slot number should be >= 2 if using Network mode or I2S mode */ |
1042 | val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET); | 932 | regmap_read(regs, CCSR_SSI_SCR, &val); |
933 | val &= CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET; | ||
1043 | if (val && slots < 2) { | 934 | if (val && slots < 2) { |
1044 | dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); | 935 | dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); |
1045 | return -EINVAL; | 936 | return -EINVAL; |
1046 | } | 937 | } |
1047 | 938 | ||
1048 | write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, | 939 | regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_DC_MASK, |
1049 | CCSR_SSI_SxCCR_DC(slots)); | 940 | CCSR_SSI_SxCCR_DC(slots)); |
1050 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, | 941 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_DC_MASK, |
1051 | CCSR_SSI_SxCCR_DC(slots)); | 942 | CCSR_SSI_SxCCR_DC(slots)); |
1052 | 943 | ||
1053 | /* The register SxMSKs needs SSI to provide essential clock due to | 944 | /* The register SxMSKs needs SSI to provide essential clock due to |
1054 | * hardware design. So we here temporarily enable SSI to set them. | 945 | * hardware design. So we here temporarily enable SSI to set them. |
1055 | */ | 946 | */ |
1056 | val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN; | 947 | regmap_read(regs, CCSR_SSI_SCR, &val); |
1057 | write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN); | 948 | val &= CCSR_SSI_SCR_SSIEN; |
949 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, | ||
950 | CCSR_SSI_SCR_SSIEN); | ||
1058 | 951 | ||
1059 | write_ssi(tx_mask, &ssi->stmsk); | 952 | regmap_write(regs, CCSR_SSI_STMSK, tx_mask); |
1060 | write_ssi(rx_mask, &ssi->srmsk); | 953 | regmap_write(regs, CCSR_SSI_SRMSK, rx_mask); |
1061 | 954 | ||
1062 | write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val); | 955 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val); |
1063 | 956 | ||
1064 | return 0; | 957 | return 0; |
1065 | } | 958 | } |
@@ -1078,11 +971,11 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1078 | { | 971 | { |
1079 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 972 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1080 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); | 973 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
1081 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 974 | struct regmap *regs = ssi_private->regs; |
1082 | unsigned long flags; | ||
1083 | 975 | ||
1084 | switch (cmd) { | 976 | switch (cmd) { |
1085 | case SNDRV_PCM_TRIGGER_START: | 977 | case SNDRV_PCM_TRIGGER_START: |
978 | case SNDRV_PCM_TRIGGER_RESUME: | ||
1086 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 979 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1087 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 980 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1088 | fsl_ssi_tx_config(ssi_private, true); | 981 | fsl_ssi_tx_config(ssi_private, true); |
@@ -1091,29 +984,23 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1091 | break; | 984 | break; |
1092 | 985 | ||
1093 | case SNDRV_PCM_TRIGGER_STOP: | 986 | case SNDRV_PCM_TRIGGER_STOP: |
987 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
1094 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 988 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
1095 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 989 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1096 | fsl_ssi_tx_config(ssi_private, false); | 990 | fsl_ssi_tx_config(ssi_private, false); |
1097 | else | 991 | else |
1098 | fsl_ssi_rx_config(ssi_private, false); | 992 | fsl_ssi_rx_config(ssi_private, false); |
1099 | |||
1100 | if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & | ||
1101 | (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { | ||
1102 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | ||
1103 | ssi_private->baudclk_locked = false; | ||
1104 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
1105 | } | ||
1106 | break; | 993 | break; |
1107 | 994 | ||
1108 | default: | 995 | default: |
1109 | return -EINVAL; | 996 | return -EINVAL; |
1110 | } | 997 | } |
1111 | 998 | ||
1112 | if (ssi_private->imx_ac97) { | 999 | if (fsl_ssi_is_ac97(ssi_private)) { |
1113 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1000 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1114 | write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); | 1001 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_TX_CLR); |
1115 | else | 1002 | else |
1116 | write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor); | 1003 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_RX_CLR); |
1117 | } | 1004 | } |
1118 | 1005 | ||
1119 | return 0; | 1006 | return 0; |
@@ -1123,7 +1010,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) | |||
1123 | { | 1010 | { |
1124 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); | 1011 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); |
1125 | 1012 | ||
1126 | if (ssi_private->ssi_on_imx && ssi_private->use_dma) { | 1013 | if (ssi_private->soc->imx && ssi_private->use_dma) { |
1127 | dai->playback_dma_data = &ssi_private->dma_params_tx; | 1014 | dai->playback_dma_data = &ssi_private->dma_params_tx; |
1128 | dai->capture_dma_data = &ssi_private->dma_params_rx; | 1015 | dai->capture_dma_data = &ssi_private->dma_params_rx; |
1129 | } | 1016 | } |
@@ -1134,6 +1021,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) | |||
1134 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { | 1021 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { |
1135 | .startup = fsl_ssi_startup, | 1022 | .startup = fsl_ssi_startup, |
1136 | .hw_params = fsl_ssi_hw_params, | 1023 | .hw_params = fsl_ssi_hw_params, |
1024 | .hw_free = fsl_ssi_hw_free, | ||
1137 | .set_fmt = fsl_ssi_set_dai_fmt, | 1025 | .set_fmt = fsl_ssi_set_dai_fmt, |
1138 | .set_sysclk = fsl_ssi_set_dai_sysclk, | 1026 | .set_sysclk = fsl_ssi_set_dai_sysclk, |
1139 | .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, | 1027 | .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, |
@@ -1184,15 +1072,10 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { | |||
1184 | 1072 | ||
1185 | static struct fsl_ssi_private *fsl_ac97_data; | 1073 | static struct fsl_ssi_private *fsl_ac97_data; |
1186 | 1074 | ||
1187 | static void fsl_ssi_ac97_init(void) | ||
1188 | { | ||
1189 | fsl_ssi_setup(fsl_ac97_data); | ||
1190 | } | ||
1191 | |||
1192 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | 1075 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, |
1193 | unsigned short val) | 1076 | unsigned short val) |
1194 | { | 1077 | { |
1195 | struct ccsr_ssi *ssi = fsl_ac97_data->ssi; | 1078 | struct regmap *regs = fsl_ac97_data->regs; |
1196 | unsigned int lreg; | 1079 | unsigned int lreg; |
1197 | unsigned int lval; | 1080 | unsigned int lval; |
1198 | 1081 | ||
@@ -1201,12 +1084,12 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
1201 | 1084 | ||
1202 | 1085 | ||
1203 | lreg = reg << 12; | 1086 | lreg = reg << 12; |
1204 | write_ssi(lreg, &ssi->sacadd); | 1087 | regmap_write(regs, CCSR_SSI_SACADD, lreg); |
1205 | 1088 | ||
1206 | lval = val << 4; | 1089 | lval = val << 4; |
1207 | write_ssi(lval , &ssi->sacdat); | 1090 | regmap_write(regs, CCSR_SSI_SACDAT, lval); |
1208 | 1091 | ||
1209 | write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK, | 1092 | regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, |
1210 | CCSR_SSI_SACNT_WR); | 1093 | CCSR_SSI_SACNT_WR); |
1211 | udelay(100); | 1094 | udelay(100); |
1212 | } | 1095 | } |
@@ -1214,19 +1097,21 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
1214 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | 1097 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, |
1215 | unsigned short reg) | 1098 | unsigned short reg) |
1216 | { | 1099 | { |
1217 | struct ccsr_ssi *ssi = fsl_ac97_data->ssi; | 1100 | struct regmap *regs = fsl_ac97_data->regs; |
1218 | 1101 | ||
1219 | unsigned short val = -1; | 1102 | unsigned short val = -1; |
1103 | u32 reg_val; | ||
1220 | unsigned int lreg; | 1104 | unsigned int lreg; |
1221 | 1105 | ||
1222 | lreg = (reg & 0x7f) << 12; | 1106 | lreg = (reg & 0x7f) << 12; |
1223 | write_ssi(lreg, &ssi->sacadd); | 1107 | regmap_write(regs, CCSR_SSI_SACADD, lreg); |
1224 | write_ssi_mask(&ssi->sacnt, CCSR_SSI_SACNT_RDWR_MASK, | 1108 | regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, |
1225 | CCSR_SSI_SACNT_RD); | 1109 | CCSR_SSI_SACNT_RD); |
1226 | 1110 | ||
1227 | udelay(100); | 1111 | udelay(100); |
1228 | 1112 | ||
1229 | val = (read_ssi(&ssi->sacdat) >> 4) & 0xffff; | 1113 | regmap_read(regs, CCSR_SSI_SACDAT, ®_val); |
1114 | val = (reg_val >> 4) & 0xffff; | ||
1230 | 1115 | ||
1231 | return val; | 1116 | return val; |
1232 | } | 1117 | } |
@@ -1251,20 +1136,105 @@ static void make_lowercase(char *s) | |||
1251 | } | 1136 | } |
1252 | } | 1137 | } |
1253 | 1138 | ||
1139 | static int fsl_ssi_imx_probe(struct platform_device *pdev, | ||
1140 | struct fsl_ssi_private *ssi_private, void __iomem *iomem) | ||
1141 | { | ||
1142 | struct device_node *np = pdev->dev.of_node; | ||
1143 | u32 dmas[4]; | ||
1144 | int ret; | ||
1145 | |||
1146 | ssi_private->clk = devm_clk_get(&pdev->dev, NULL); | ||
1147 | if (IS_ERR(ssi_private->clk)) { | ||
1148 | ret = PTR_ERR(ssi_private->clk); | ||
1149 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | ||
1150 | return ret; | ||
1151 | } | ||
1152 | |||
1153 | ret = clk_prepare_enable(ssi_private->clk); | ||
1154 | if (ret) { | ||
1155 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | ||
1156 | return ret; | ||
1157 | } | ||
1158 | |||
1159 | /* For those SLAVE implementations, we ingore non-baudclk cases | ||
1160 | * and, instead, abandon MASTER mode that needs baud clock. | ||
1161 | */ | ||
1162 | ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); | ||
1163 | if (IS_ERR(ssi_private->baudclk)) | ||
1164 | dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", | ||
1165 | PTR_ERR(ssi_private->baudclk)); | ||
1166 | |||
1167 | /* | ||
1168 | * We have burstsize be "fifo_depth - 2" to match the SSI | ||
1169 | * watermark setting in fsl_ssi_startup(). | ||
1170 | */ | ||
1171 | ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2; | ||
1172 | ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2; | ||
1173 | ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; | ||
1174 | ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; | ||
1175 | |||
1176 | ret = !of_property_read_u32_array(np, "dmas", dmas, 4); | ||
1177 | if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { | ||
1178 | ssi_private->use_dual_fifo = true; | ||
1179 | /* When using dual fifo mode, we need to keep watermark | ||
1180 | * as even numbers due to dma script limitation. | ||
1181 | */ | ||
1182 | ssi_private->dma_params_tx.maxburst &= ~0x1; | ||
1183 | ssi_private->dma_params_rx.maxburst &= ~0x1; | ||
1184 | } | ||
1185 | |||
1186 | if (!ssi_private->use_dma) { | ||
1187 | |||
1188 | /* | ||
1189 | * Some boards use an incompatible codec. To get it | ||
1190 | * working, we are using imx-fiq-pcm-audio, that | ||
1191 | * can handle those codecs. DMA is not possible in this | ||
1192 | * situation. | ||
1193 | */ | ||
1194 | |||
1195 | ssi_private->fiq_params.irq = ssi_private->irq; | ||
1196 | ssi_private->fiq_params.base = iomem; | ||
1197 | ssi_private->fiq_params.dma_params_rx = | ||
1198 | &ssi_private->dma_params_rx; | ||
1199 | ssi_private->fiq_params.dma_params_tx = | ||
1200 | &ssi_private->dma_params_tx; | ||
1201 | |||
1202 | ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); | ||
1203 | if (ret) | ||
1204 | goto error_pcm; | ||
1205 | } else { | ||
1206 | ret = imx_pcm_dma_init(pdev); | ||
1207 | if (ret) | ||
1208 | goto error_pcm; | ||
1209 | } | ||
1210 | |||
1211 | return 0; | ||
1212 | |||
1213 | error_pcm: | ||
1214 | clk_disable_unprepare(ssi_private->clk); | ||
1215 | |||
1216 | return ret; | ||
1217 | } | ||
1218 | |||
1219 | static void fsl_ssi_imx_clean(struct platform_device *pdev, | ||
1220 | struct fsl_ssi_private *ssi_private) | ||
1221 | { | ||
1222 | if (!ssi_private->use_dma) | ||
1223 | imx_pcm_fiq_exit(pdev); | ||
1224 | clk_disable_unprepare(ssi_private->clk); | ||
1225 | } | ||
1226 | |||
1254 | static int fsl_ssi_probe(struct platform_device *pdev) | 1227 | static int fsl_ssi_probe(struct platform_device *pdev) |
1255 | { | 1228 | { |
1256 | struct fsl_ssi_private *ssi_private; | 1229 | struct fsl_ssi_private *ssi_private; |
1257 | int ret = 0; | 1230 | int ret = 0; |
1258 | struct device_attribute *dev_attr = NULL; | ||
1259 | struct device_node *np = pdev->dev.of_node; | 1231 | struct device_node *np = pdev->dev.of_node; |
1260 | const struct of_device_id *of_id; | 1232 | const struct of_device_id *of_id; |
1261 | enum fsl_ssi_type hw_type; | ||
1262 | const char *p, *sprop; | 1233 | const char *p, *sprop; |
1263 | const uint32_t *iprop; | 1234 | const uint32_t *iprop; |
1264 | struct resource res; | 1235 | struct resource res; |
1236 | void __iomem *iomem; | ||
1265 | char name[64]; | 1237 | char name[64]; |
1266 | bool shared; | ||
1267 | bool ac97 = false; | ||
1268 | 1238 | ||
1269 | /* SSIs that are not connected on the board should have a | 1239 | /* SSIs that are not connected on the board should have a |
1270 | * status = "disabled" | 1240 | * status = "disabled" |
@@ -1274,39 +1244,35 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1274 | return -ENODEV; | 1244 | return -ENODEV; |
1275 | 1245 | ||
1276 | of_id = of_match_device(fsl_ssi_ids, &pdev->dev); | 1246 | of_id = of_match_device(fsl_ssi_ids, &pdev->dev); |
1277 | if (!of_id) | 1247 | if (!of_id || !of_id->data) |
1278 | return -EINVAL; | 1248 | return -EINVAL; |
1279 | hw_type = (enum fsl_ssi_type) of_id->data; | ||
1280 | 1249 | ||
1281 | sprop = of_get_property(np, "fsl,mode", NULL); | 1250 | ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), |
1282 | if (!sprop) { | 1251 | GFP_KERNEL); |
1283 | dev_err(&pdev->dev, "fsl,mode property is necessary\n"); | ||
1284 | return -EINVAL; | ||
1285 | } | ||
1286 | if (!strcmp(sprop, "ac97-slave")) | ||
1287 | ac97 = true; | ||
1288 | |||
1289 | /* The DAI name is the last part of the full name of the node. */ | ||
1290 | p = strrchr(np->full_name, '/') + 1; | ||
1291 | ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private) + strlen(p), | ||
1292 | GFP_KERNEL); | ||
1293 | if (!ssi_private) { | 1252 | if (!ssi_private) { |
1294 | dev_err(&pdev->dev, "could not allocate DAI object\n"); | 1253 | dev_err(&pdev->dev, "could not allocate DAI object\n"); |
1295 | return -ENOMEM; | 1254 | return -ENOMEM; |
1296 | } | 1255 | } |
1297 | 1256 | ||
1298 | strcpy(ssi_private->name, p); | 1257 | ssi_private->soc = of_id->data; |
1258 | |||
1259 | sprop = of_get_property(np, "fsl,mode", NULL); | ||
1260 | if (sprop) { | ||
1261 | if (!strcmp(sprop, "ac97-slave")) | ||
1262 | ssi_private->dai_fmt = SND_SOC_DAIFMT_AC97; | ||
1263 | else if (!strcmp(sprop, "i2s-slave")) | ||
1264 | ssi_private->dai_fmt = SND_SOC_DAIFMT_I2S | | ||
1265 | SND_SOC_DAIFMT_CBM_CFM; | ||
1266 | } | ||
1299 | 1267 | ||
1300 | ssi_private->use_dma = !of_property_read_bool(np, | 1268 | ssi_private->use_dma = !of_property_read_bool(np, |
1301 | "fsl,fiq-stream-filter"); | 1269 | "fsl,fiq-stream-filter"); |
1302 | ssi_private->hw_type = hw_type; | ||
1303 | 1270 | ||
1304 | if (ac97) { | 1271 | if (fsl_ssi_is_ac97(ssi_private)) { |
1305 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, | 1272 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, |
1306 | sizeof(fsl_ssi_ac97_dai)); | 1273 | sizeof(fsl_ssi_ac97_dai)); |
1307 | 1274 | ||
1308 | fsl_ac97_data = ssi_private; | 1275 | fsl_ac97_data = ssi_private; |
1309 | ssi_private->imx_ac97 = true; | ||
1310 | 1276 | ||
1311 | snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); | 1277 | snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); |
1312 | } else { | 1278 | } else { |
@@ -1314,7 +1280,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1314 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, | 1280 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, |
1315 | sizeof(fsl_ssi_dai_template)); | 1281 | sizeof(fsl_ssi_dai_template)); |
1316 | } | 1282 | } |
1317 | ssi_private->cpu_dai_drv.name = ssi_private->name; | 1283 | ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev); |
1318 | 1284 | ||
1319 | /* Get the addresses and IRQ */ | 1285 | /* Get the addresses and IRQ */ |
1320 | ret = of_address_to_resource(np, 0, &res); | 1286 | ret = of_address_to_resource(np, 0, &res); |
@@ -1322,12 +1288,20 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1322 | dev_err(&pdev->dev, "could not determine device resources\n"); | 1288 | dev_err(&pdev->dev, "could not determine device resources\n"); |
1323 | return ret; | 1289 | return ret; |
1324 | } | 1290 | } |
1325 | ssi_private->ssi = of_iomap(np, 0); | 1291 | ssi_private->ssi_phys = res.start; |
1326 | if (!ssi_private->ssi) { | 1292 | |
1293 | iomem = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); | ||
1294 | if (!iomem) { | ||
1327 | dev_err(&pdev->dev, "could not map device resources\n"); | 1295 | dev_err(&pdev->dev, "could not map device resources\n"); |
1328 | return -ENOMEM; | 1296 | return -ENOMEM; |
1329 | } | 1297 | } |
1330 | ssi_private->ssi_phys = res.start; | 1298 | |
1299 | ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, | ||
1300 | &fsl_ssi_regconfig); | ||
1301 | if (IS_ERR(ssi_private->regs)) { | ||
1302 | dev_err(&pdev->dev, "Failed to init register map\n"); | ||
1303 | return PTR_ERR(ssi_private->regs); | ||
1304 | } | ||
1331 | 1305 | ||
1332 | ssi_private->irq = irq_of_parse_and_map(np, 0); | 1306 | ssi_private->irq = irq_of_parse_and_map(np, 0); |
1333 | if (!ssi_private->irq) { | 1307 | if (!ssi_private->irq) { |
@@ -1350,180 +1324,43 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1350 | /* Older 8610 DTs didn't have the fifo-depth property */ | 1324 | /* Older 8610 DTs didn't have the fifo-depth property */ |
1351 | ssi_private->fifo_depth = 8; | 1325 | ssi_private->fifo_depth = 8; |
1352 | 1326 | ||
1353 | ssi_private->baudclk_locked = false; | 1327 | dev_set_drvdata(&pdev->dev, ssi_private); |
1354 | spin_lock_init(&ssi_private->baudclk_lock); | ||
1355 | |||
1356 | /* | ||
1357 | * imx51 and later SoCs have a slightly different IP that allows the | ||
1358 | * SSI configuration while the SSI unit is running. | ||
1359 | * | ||
1360 | * More important, it is necessary on those SoCs to configure the | ||
1361 | * sperate TX/RX DMA bits just before starting the stream | ||
1362 | * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi | ||
1363 | * sends any DMA requests to the SDMA unit, otherwise it is not defined | ||
1364 | * how the SDMA unit handles the DMA request. | ||
1365 | * | ||
1366 | * SDMA units are present on devices starting at imx35 but the imx35 | ||
1367 | * reference manual states that the DMA bits should not be changed | ||
1368 | * while the SSI unit is running (SSIEN). So we support the necessary | ||
1369 | * online configuration of fsl-ssi starting at imx51. | ||
1370 | */ | ||
1371 | switch (hw_type) { | ||
1372 | case FSL_SSI_MCP8610: | ||
1373 | case FSL_SSI_MX21: | ||
1374 | case FSL_SSI_MX35: | ||
1375 | ssi_private->offline_config = true; | ||
1376 | break; | ||
1377 | case FSL_SSI_MX51: | ||
1378 | ssi_private->offline_config = false; | ||
1379 | break; | ||
1380 | } | ||
1381 | |||
1382 | if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 || | ||
1383 | hw_type == FSL_SSI_MX35) { | ||
1384 | u32 dma_events[2], dmas[4]; | ||
1385 | ssi_private->ssi_on_imx = true; | ||
1386 | 1328 | ||
1387 | ssi_private->clk = devm_clk_get(&pdev->dev, NULL); | 1329 | if (ssi_private->soc->imx) { |
1388 | if (IS_ERR(ssi_private->clk)) { | 1330 | ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem); |
1389 | ret = PTR_ERR(ssi_private->clk); | 1331 | if (ret) |
1390 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | ||
1391 | goto error_irqmap; | 1332 | goto error_irqmap; |
1392 | } | 1333 | } |
1393 | ret = clk_prepare_enable(ssi_private->clk); | ||
1394 | if (ret) { | ||
1395 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", | ||
1396 | ret); | ||
1397 | goto error_irqmap; | ||
1398 | } | ||
1399 | |||
1400 | /* For those SLAVE implementations, we ingore non-baudclk cases | ||
1401 | * and, instead, abandon MASTER mode that needs baud clock. | ||
1402 | */ | ||
1403 | ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); | ||
1404 | if (IS_ERR(ssi_private->baudclk)) | ||
1405 | dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", | ||
1406 | PTR_ERR(ssi_private->baudclk)); | ||
1407 | else | ||
1408 | clk_prepare_enable(ssi_private->baudclk); | ||
1409 | |||
1410 | /* | ||
1411 | * We have burstsize be "fifo_depth - 2" to match the SSI | ||
1412 | * watermark setting in fsl_ssi_startup(). | ||
1413 | */ | ||
1414 | ssi_private->dma_params_tx.maxburst = | ||
1415 | ssi_private->fifo_depth - 2; | ||
1416 | ssi_private->dma_params_rx.maxburst = | ||
1417 | ssi_private->fifo_depth - 2; | ||
1418 | ssi_private->dma_params_tx.addr = | ||
1419 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); | ||
1420 | ssi_private->dma_params_rx.addr = | ||
1421 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); | ||
1422 | ssi_private->dma_params_tx.filter_data = | ||
1423 | &ssi_private->filter_data_tx; | ||
1424 | ssi_private->dma_params_rx.filter_data = | ||
1425 | &ssi_private->filter_data_rx; | ||
1426 | if (!of_property_read_bool(pdev->dev.of_node, "dmas") && | ||
1427 | ssi_private->use_dma) { | ||
1428 | /* | ||
1429 | * FIXME: This is a temporary solution until all | ||
1430 | * necessary dma drivers support the generic dma | ||
1431 | * bindings. | ||
1432 | */ | ||
1433 | ret = of_property_read_u32_array(pdev->dev.of_node, | ||
1434 | "fsl,ssi-dma-events", dma_events, 2); | ||
1435 | if (ret && ssi_private->use_dma) { | ||
1436 | dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n"); | ||
1437 | goto error_clk; | ||
1438 | } | ||
1439 | } | ||
1440 | /* Should this be merge with the above? */ | ||
1441 | if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4) | ||
1442 | && dmas[2] == IMX_DMATYPE_SSI_DUAL) { | ||
1443 | ssi_private->use_dual_fifo = true; | ||
1444 | /* When using dual fifo mode, we need to keep watermark | ||
1445 | * as even numbers due to dma script limitation. | ||
1446 | */ | ||
1447 | ssi_private->dma_params_tx.maxburst &= ~0x1; | ||
1448 | ssi_private->dma_params_rx.maxburst &= ~0x1; | ||
1449 | } | ||
1450 | |||
1451 | shared = of_device_is_compatible(of_get_parent(np), | ||
1452 | "fsl,spba-bus"); | ||
1453 | 1334 | ||
1454 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx, | 1335 | ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, |
1455 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1336 | &ssi_private->cpu_dai_drv, 1); |
1456 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, | 1337 | if (ret) { |
1457 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1338 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); |
1339 | goto error_asoc_register; | ||
1458 | } | 1340 | } |
1459 | 1341 | ||
1460 | /* | ||
1461 | * Enable interrupts only for MCP8610 and MX51. The other MXs have | ||
1462 | * different writeable interrupt status registers. | ||
1463 | */ | ||
1464 | if (ssi_private->use_dma) { | 1342 | if (ssi_private->use_dma) { |
1465 | /* The 'name' should not have any slashes in it. */ | ||
1466 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, | 1343 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, |
1467 | fsl_ssi_isr, 0, ssi_private->name, | 1344 | fsl_ssi_isr, 0, dev_name(&pdev->dev), |
1468 | ssi_private); | 1345 | ssi_private); |
1469 | ssi_private->irq_stats = true; | ||
1470 | if (ret < 0) { | 1346 | if (ret < 0) { |
1471 | dev_err(&pdev->dev, "could not claim irq %u\n", | 1347 | dev_err(&pdev->dev, "could not claim irq %u\n", |
1472 | ssi_private->irq); | 1348 | ssi_private->irq); |
1473 | goto error_clk; | 1349 | goto error_irq; |
1474 | } | 1350 | } |
1475 | } | 1351 | } |
1476 | 1352 | ||
1477 | /* Register with ASoC */ | 1353 | ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); |
1478 | dev_set_drvdata(&pdev->dev, ssi_private); | ||
1479 | |||
1480 | ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, | ||
1481 | &ssi_private->cpu_dai_drv, 1); | ||
1482 | if (ret) { | ||
1483 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | ||
1484 | goto error_dev; | ||
1485 | } | ||
1486 | |||
1487 | ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev); | ||
1488 | if (ret) | 1354 | if (ret) |
1489 | goto error_dbgfs; | 1355 | goto error_asoc_register; |
1490 | |||
1491 | if (ssi_private->ssi_on_imx) { | ||
1492 | if (!ssi_private->use_dma) { | ||
1493 | |||
1494 | /* | ||
1495 | * Some boards use an incompatible codec. To get it | ||
1496 | * working, we are using imx-fiq-pcm-audio, that | ||
1497 | * can handle those codecs. DMA is not possible in this | ||
1498 | * situation. | ||
1499 | */ | ||
1500 | |||
1501 | ssi_private->fiq_params.irq = ssi_private->irq; | ||
1502 | ssi_private->fiq_params.base = ssi_private->ssi; | ||
1503 | ssi_private->fiq_params.dma_params_rx = | ||
1504 | &ssi_private->dma_params_rx; | ||
1505 | ssi_private->fiq_params.dma_params_tx = | ||
1506 | &ssi_private->dma_params_tx; | ||
1507 | |||
1508 | ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); | ||
1509 | if (ret) | ||
1510 | goto error_pcm; | ||
1511 | } else { | ||
1512 | ret = imx_pcm_dma_init(pdev); | ||
1513 | if (ret) | ||
1514 | goto error_pcm; | ||
1515 | } | ||
1516 | } | ||
1517 | 1356 | ||
1518 | /* | 1357 | /* |
1519 | * If codec-handle property is missing from SSI node, we assume | 1358 | * If codec-handle property is missing from SSI node, we assume |
1520 | * that the machine driver uses new binding which does not require | 1359 | * that the machine driver uses new binding which does not require |
1521 | * SSI driver to trigger machine driver's probe. | 1360 | * SSI driver to trigger machine driver's probe. |
1522 | */ | 1361 | */ |
1523 | if (!of_get_property(np, "codec-handle", NULL)) { | 1362 | if (!of_get_property(np, "codec-handle", NULL)) |
1524 | ssi_private->new_binding = true; | ||
1525 | goto done; | 1363 | goto done; |
1526 | } | ||
1527 | 1364 | ||
1528 | /* Trigger the machine driver's probe function. The platform driver | 1365 | /* Trigger the machine driver's probe function. The platform driver |
1529 | * name of the machine driver is taken from /compatible property of the | 1366 | * name of the machine driver is taken from /compatible property of the |
@@ -1543,37 +1380,27 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1543 | if (IS_ERR(ssi_private->pdev)) { | 1380 | if (IS_ERR(ssi_private->pdev)) { |
1544 | ret = PTR_ERR(ssi_private->pdev); | 1381 | ret = PTR_ERR(ssi_private->pdev); |
1545 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); | 1382 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); |
1546 | goto error_dai; | 1383 | goto error_sound_card; |
1547 | } | 1384 | } |
1548 | 1385 | ||
1549 | done: | 1386 | done: |
1550 | if (ssi_private->imx_ac97) | 1387 | if (ssi_private->dai_fmt) |
1551 | fsl_ssi_ac97_init(); | 1388 | _fsl_ssi_set_dai_fmt(ssi_private, ssi_private->dai_fmt); |
1552 | 1389 | ||
1553 | return 0; | 1390 | return 0; |
1554 | 1391 | ||
1555 | error_dai: | 1392 | error_sound_card: |
1556 | if (ssi_private->ssi_on_imx && !ssi_private->use_dma) | 1393 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1557 | imx_pcm_fiq_exit(pdev); | ||
1558 | |||
1559 | error_pcm: | ||
1560 | fsl_ssi_debugfs_remove(ssi_private); | ||
1561 | 1394 | ||
1562 | error_dbgfs: | 1395 | error_irq: |
1563 | snd_soc_unregister_component(&pdev->dev); | 1396 | snd_soc_unregister_component(&pdev->dev); |
1564 | 1397 | ||
1565 | error_dev: | 1398 | error_asoc_register: |
1566 | device_remove_file(&pdev->dev, dev_attr); | 1399 | if (ssi_private->soc->imx) |
1567 | 1400 | fsl_ssi_imx_clean(pdev, ssi_private); | |
1568 | error_clk: | ||
1569 | if (ssi_private->ssi_on_imx) { | ||
1570 | if (!IS_ERR(ssi_private->baudclk)) | ||
1571 | clk_disable_unprepare(ssi_private->baudclk); | ||
1572 | clk_disable_unprepare(ssi_private->clk); | ||
1573 | } | ||
1574 | 1401 | ||
1575 | error_irqmap: | 1402 | error_irqmap: |
1576 | if (ssi_private->irq_stats) | 1403 | if (ssi_private->use_dma) |
1577 | irq_dispose_mapping(ssi_private->irq); | 1404 | irq_dispose_mapping(ssi_private->irq); |
1578 | 1405 | ||
1579 | return ret; | 1406 | return ret; |
@@ -1583,17 +1410,16 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1583 | { | 1410 | { |
1584 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); | 1411 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); |
1585 | 1412 | ||
1586 | fsl_ssi_debugfs_remove(ssi_private); | 1413 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1587 | 1414 | ||
1588 | if (!ssi_private->new_binding) | 1415 | if (ssi_private->pdev) |
1589 | platform_device_unregister(ssi_private->pdev); | 1416 | platform_device_unregister(ssi_private->pdev); |
1590 | snd_soc_unregister_component(&pdev->dev); | 1417 | snd_soc_unregister_component(&pdev->dev); |
1591 | if (ssi_private->ssi_on_imx) { | 1418 | |
1592 | if (!IS_ERR(ssi_private->baudclk)) | 1419 | if (ssi_private->soc->imx) |
1593 | clk_disable_unprepare(ssi_private->baudclk); | 1420 | fsl_ssi_imx_clean(pdev, ssi_private); |
1594 | clk_disable_unprepare(ssi_private->clk); | 1421 | |
1595 | } | 1422 | if (ssi_private->use_dma) |
1596 | if (ssi_private->irq_stats) | ||
1597 | irq_dispose_mapping(ssi_private->irq); | 1423 | irq_dispose_mapping(ssi_private->irq); |
1598 | 1424 | ||
1599 | return 0; | 1425 | return 0; |