diff options
author | Stephen Warren <swarren@nvidia.com> | 2011-11-23 15:33:25 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-11-23 16:34:48 -0500 |
commit | d4a2eca781bfd7323bfd98dbc7fd63c7d613fef2 (patch) | |
tree | 1f12eb90f30566ad0068eb060efa4baf5078ed68 /sound/soc/tegra | |
parent | 16c88583dca05034f284ad5c52f007a47673cf35 (diff) |
ASoC: Tegra I2S: Remove dependency on pdev->id
When devices are instantiated from device-tree, pdev->id is set to -1.
Rework the driver so it doesn't depend on the ID.
Tegra I2S instantiated from board files are configured with pdev
name "tegra-i2s" and ID 0 or 1. The driver core then names the
device "tegra-i2s.0" or "tegra-i2s.1". This is not changing.
When a device is instantiated from device-tree, it will have
pdev->name="" and pdev->id=-1. For this reason, the pdev->id value is
not something we can rely on.
This patch doesn't actually change any names though:
When a device is instantiated from device-tree, the overall device name
will be "${unit_address}.${node_name}". This causes issues such as
clk_get() failures due to lack of a device-name match. To solve that,
AUXDATA was invented, to force a specific device name, thus allowing
dev_name() to return the same as the non-device-tree case. Tegra
currently uses AUXDATA for the I2S controllers. Eventually, AUXDATA will
go away, most likely replaced by phandle-based references within the
device tree.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r-- | sound/soc/tegra/tegra_i2s.c | 72 | ||||
-rw-r--r-- | sound/soc/tegra/tegra_i2s.h | 1 |
2 files changed, 24 insertions, 49 deletions
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 1acbb5541772..ca4d0c0a913e 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c | |||
@@ -98,13 +98,11 @@ static const struct file_operations tegra_i2s_debug_fops = { | |||
98 | .release = single_release, | 98 | .release = single_release, |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) | 101 | static void tegra_i2s_debug_add(struct tegra_i2s *i2s) |
102 | { | 102 | { |
103 | char name[] = DRV_NAME ".0"; | 103 | i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO, |
104 | 104 | snd_soc_debugfs_root, i2s, | |
105 | snprintf(name, sizeof(name), DRV_NAME".%1d", id); | 105 | &tegra_i2s_debug_fops); |
106 | i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root, | ||
107 | i2s, &tegra_i2s_debug_fops); | ||
108 | } | 106 | } |
109 | 107 | ||
110 | static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) | 108 | static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) |
@@ -311,43 +309,22 @@ static const struct snd_soc_dai_ops tegra_i2s_dai_ops = { | |||
311 | .trigger = tegra_i2s_trigger, | 309 | .trigger = tegra_i2s_trigger, |
312 | }; | 310 | }; |
313 | 311 | ||
314 | static struct snd_soc_dai_driver tegra_i2s_dai[] = { | 312 | static const struct snd_soc_dai_driver tegra_i2s_dai_template = { |
315 | { | 313 | .probe = tegra_i2s_probe, |
316 | .name = DRV_NAME ".0", | 314 | .playback = { |
317 | .probe = tegra_i2s_probe, | 315 | .channels_min = 2, |
318 | .playback = { | 316 | .channels_max = 2, |
319 | .channels_min = 2, | 317 | .rates = SNDRV_PCM_RATE_8000_96000, |
320 | .channels_max = 2, | 318 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
321 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
322 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
323 | }, | ||
324 | .capture = { | ||
325 | .channels_min = 2, | ||
326 | .channels_max = 2, | ||
327 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
328 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
329 | }, | ||
330 | .ops = &tegra_i2s_dai_ops, | ||
331 | .symmetric_rates = 1, | ||
332 | }, | 319 | }, |
333 | { | 320 | .capture = { |
334 | .name = DRV_NAME ".1", | 321 | .channels_min = 2, |
335 | .probe = tegra_i2s_probe, | 322 | .channels_max = 2, |
336 | .playback = { | 323 | .rates = SNDRV_PCM_RATE_8000_96000, |
337 | .channels_min = 2, | 324 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
338 | .channels_max = 2, | ||
339 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
340 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
341 | }, | ||
342 | .capture = { | ||
343 | .channels_min = 2, | ||
344 | .channels_max = 2, | ||
345 | .rates = SNDRV_PCM_RATE_8000_96000, | ||
346 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
347 | }, | ||
348 | .ops = &tegra_i2s_dai_ops, | ||
349 | .symmetric_rates = 1, | ||
350 | }, | 325 | }, |
326 | .ops = &tegra_i2s_dai_ops, | ||
327 | .symmetric_rates = 1, | ||
351 | }; | 328 | }; |
352 | 329 | ||
353 | static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) | 330 | static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) |
@@ -356,12 +333,6 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) | |||
356 | struct resource *mem, *memregion, *dmareq; | 333 | struct resource *mem, *memregion, *dmareq; |
357 | int ret; | 334 | int ret; |
358 | 335 | ||
359 | if ((pdev->id < 0) || | ||
360 | (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) { | ||
361 | dev_err(&pdev->dev, "ID %d out of range\n", pdev->id); | ||
362 | return -EINVAL; | ||
363 | } | ||
364 | |||
365 | i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL); | 336 | i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL); |
366 | if (!i2s) { | 337 | if (!i2s) { |
367 | dev_err(&pdev->dev, "Can't allocate tegra_i2s\n"); | 338 | dev_err(&pdev->dev, "Can't allocate tegra_i2s\n"); |
@@ -370,6 +341,9 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) | |||
370 | } | 341 | } |
371 | dev_set_drvdata(&pdev->dev, i2s); | 342 | dev_set_drvdata(&pdev->dev, i2s); |
372 | 343 | ||
344 | i2s->dai = tegra_i2s_dai_template; | ||
345 | i2s->dai.name = dev_name(&pdev->dev); | ||
346 | |||
373 | i2s->clk_i2s = clk_get(&pdev->dev, NULL); | 347 | i2s->clk_i2s = clk_get(&pdev->dev, NULL); |
374 | if (IS_ERR(i2s->clk_i2s)) { | 348 | if (IS_ERR(i2s->clk_i2s)) { |
375 | dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); | 349 | dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); |
@@ -418,14 +392,14 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) | |||
418 | 392 | ||
419 | i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED; | 393 | i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED; |
420 | 394 | ||
421 | ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]); | 395 | ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); |
422 | if (ret) { | 396 | if (ret) { |
423 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); | 397 | dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); |
424 | ret = -ENOMEM; | 398 | ret = -ENOMEM; |
425 | goto err_clk_put; | 399 | goto err_clk_put; |
426 | } | 400 | } |
427 | 401 | ||
428 | tegra_i2s_debug_add(i2s, pdev->id); | 402 | tegra_i2s_debug_add(i2s); |
429 | 403 | ||
430 | return 0; | 404 | return 0; |
431 | 405 | ||
diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h index 2b38a096f46c..15ce1e2e8bde 100644 --- a/sound/soc/tegra/tegra_i2s.h +++ b/sound/soc/tegra/tegra_i2s.h | |||
@@ -153,6 +153,7 @@ | |||
153 | #define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT) | 153 | #define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT) |
154 | 154 | ||
155 | struct tegra_i2s { | 155 | struct tegra_i2s { |
156 | struct snd_soc_dai_driver dai; | ||
156 | struct clk *clk_i2s; | 157 | struct clk *clk_i2s; |
157 | int clk_refs; | 158 | int clk_refs; |
158 | struct tegra_pcm_dma_params capture_dma_data; | 159 | struct tegra_pcm_dma_params capture_dma_data; |