From 071106ecf68c401173c58808b1cf5f68cc50d390 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 05 Jan 2024 08:39:27 +0000 Subject: [PATCH] change wifi driver to cypress --- kernel/sound/soc/jz4740/jz4740-i2s.c | 154 +++++++++++++++++++++++++++++++-------------------- 1 files changed, 94 insertions(+), 60 deletions(-) diff --git a/kernel/sound/soc/jz4740/jz4740-i2s.c b/kernel/sound/soc/jz4740/jz4740-i2s.c index 2c6b0ac..fb6476b 100644 --- a/kernel/sound/soc/jz4740/jz4740-i2s.c +++ b/kernel/sound/soc/jz4740/jz4740-i2s.c @@ -1,15 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/init.h> @@ -58,12 +49,8 @@ #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12 #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8 -#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24 -#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16 -#define JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_MASK \ - (0xf << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) -#define JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_MASK \ - (0x1f << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) +#define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24 +#define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16 #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19) #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16) @@ -72,7 +59,8 @@ #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11) #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10) #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9) -#define JZ_AIC_CTRL_FLUSH BIT(8) +#define JZ_AIC_CTRL_TFLUSH BIT(8) +#define JZ_AIC_CTRL_RFLUSH BIT(7) #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6) #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5) #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4) @@ -99,7 +87,16 @@ enum jz47xx_i2s_version { JZ_I2S_JZ4740, + JZ_I2S_JZ4760, + JZ_I2S_JZ4770, JZ_I2S_JZ4780, +}; + +struct i2s_soc_info { + enum jz47xx_i2s_version version; + struct snd_soc_dai_driver *dai; + + bool shared_fifo_flush; }; struct jz4740_i2s { @@ -113,7 +110,7 @@ struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data; - enum jz47xx_i2s_version version; + const struct i2s_soc_info *soc_info; }; static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s, @@ -128,19 +125,44 @@ writel(value, i2s->base + reg); } +static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s, + unsigned int reg, uint32_t bits) +{ + uint32_t value = jz4740_i2s_read(i2s, reg); + value |= bits; + jz4740_i2s_write(i2s, reg, value); +} + static int jz4740_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); - uint32_t conf, ctrl; + uint32_t conf; int ret; - if (dai->active) + /* + * When we can flush FIFOs independently, only flush the FIFO + * that is starting up. We can do this when the DAI is active + * because it does not disturb other active substreams. + */ + if (!i2s->soc_info->shared_fifo_flush) { + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH); + else + jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH); + } + + if (snd_soc_dai_active(dai)) return 0; - ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL); - ctrl |= JZ_AIC_CTRL_FLUSH; - jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl); + /* + * When there is a shared flush bit for both FIFOs, the TFLUSH + * bit flushes both FIFOs. Flushing while the DAI is active would + * cause FIFO underruns in other active substreams so we have to + * guard this behind the snd_soc_dai_active() check. + */ + if (i2s->soc_info->shared_fifo_flush) + jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH); ret = clk_prepare_enable(i2s->clk_i2s); if (ret) @@ -159,7 +181,7 @@ struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); uint32_t conf; - if (dai->active) + if (snd_soc_dai_active(dai)) return; conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); @@ -293,7 +315,7 @@ ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK; ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET; - if (i2s->version >= JZ_I2S_JZ4780) { + if (i2s->soc_info->version >= JZ_I2S_JZ4770) { div_reg &= ~I2SDIV_IDV_MASK; div_reg |= (div - 1) << I2SDIV_IDV_SHIFT; } else { @@ -337,12 +359,12 @@ return ret; } -static int jz4740_i2s_suspend(struct snd_soc_dai *dai) +static int jz4740_i2s_suspend(struct snd_soc_component *component) { - struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); + struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component); uint32_t conf; - if (dai->active) { + if (snd_soc_component_active(component)) { conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF); conf &= ~JZ_AIC_CONF_ENABLE; jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf); @@ -355,9 +377,9 @@ return 0; } -static int jz4740_i2s_resume(struct snd_soc_dai *dai) +static int jz4740_i2s_resume(struct snd_soc_component *component) { - struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai); + struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component); uint32_t conf; int ret; @@ -365,7 +387,7 @@ if (ret) return ret; - if (dai->active) { + if (snd_soc_component_active(component)) { ret = clk_prepare_enable(i2s->clk_i2s); if (ret) { clk_disable_unprepare(i2s->clk_aic); @@ -411,9 +433,9 @@ snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, &i2s->capture_dma_data); - if (i2s->version >= JZ_I2S_JZ4780) { - conf = (7 << JZ4780_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | - (8 << JZ4780_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | + if (i2s->soc_info->version >= JZ_I2S_JZ4760) { + conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) | + (8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) | JZ_AIC_CONF_OVERFLOW_PLAY_LAST | JZ_AIC_CONF_I2S | JZ_AIC_CONF_INTERNAL_CODEC; @@ -468,11 +490,20 @@ }, .symmetric_rates = 1, .ops = &jz4740_i2s_dai_ops, - .suspend = jz4740_i2s_suspend, - .resume = jz4740_i2s_resume, }; -static struct snd_soc_dai_driver jz4780_i2s_dai = { +static const struct i2s_soc_info jz4740_i2s_soc_info = { + .version = JZ_I2S_JZ4740, + .dai = &jz4740_i2s_dai, + .shared_fifo_flush = true, +}; + +static const struct i2s_soc_info jz4760_i2s_soc_info = { + .version = JZ_I2S_JZ4760, + .dai = &jz4740_i2s_dai, +}; + +static struct snd_soc_dai_driver jz4770_i2s_dai = { .probe = jz4740_i2s_dai_probe, .remove = jz4740_i2s_dai_remove, .playback = { @@ -488,66 +519,69 @@ .formats = JZ4740_I2S_FMTS, }, .ops = &jz4740_i2s_dai_ops, - .suspend = jz4740_i2s_suspend, - .resume = jz4740_i2s_resume, +}; + +static const struct i2s_soc_info jz4770_i2s_soc_info = { + .version = JZ_I2S_JZ4770, + .dai = &jz4770_i2s_dai, +}; + +static const struct i2s_soc_info jz4780_i2s_soc_info = { + .version = JZ_I2S_JZ4780, + .dai = &jz4770_i2s_dai, }; static const struct snd_soc_component_driver jz4740_i2s_component = { .name = "jz4740-i2s", + .suspend = jz4740_i2s_suspend, + .resume = jz4740_i2s_resume, }; -#ifdef CONFIG_OF static const struct of_device_id jz4740_of_matches[] = { - { .compatible = "ingenic,jz4740-i2s", .data = (void *)JZ_I2S_JZ4740 }, - { .compatible = "ingenic,jz4780-i2s", .data = (void *)JZ_I2S_JZ4780 }, + { .compatible = "ingenic,jz4740-i2s", .data = &jz4740_i2s_soc_info }, + { .compatible = "ingenic,jz4760-i2s", .data = &jz4760_i2s_soc_info }, + { .compatible = "ingenic,jz4770-i2s", .data = &jz4770_i2s_soc_info }, + { .compatible = "ingenic,jz4780-i2s", .data = &jz4780_i2s_soc_info }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, jz4740_of_matches); -#endif static int jz4740_i2s_dev_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct jz4740_i2s *i2s; struct resource *mem; int ret; - const struct of_device_id *match; - i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); + i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) return -ENOMEM; - match = of_match_device(jz4740_of_matches, &pdev->dev); - if (match) - i2s->version = (enum jz47xx_i2s_version)match->data; + i2s->soc_info = device_get_match_data(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - i2s->base = devm_ioremap_resource(&pdev->dev, mem); + i2s->base = devm_ioremap_resource(dev, mem); if (IS_ERR(i2s->base)) return PTR_ERR(i2s->base); i2s->phys_base = mem->start; - i2s->clk_aic = devm_clk_get(&pdev->dev, "aic"); + i2s->clk_aic = devm_clk_get(dev, "aic"); if (IS_ERR(i2s->clk_aic)) return PTR_ERR(i2s->clk_aic); - i2s->clk_i2s = devm_clk_get(&pdev->dev, "i2s"); + i2s->clk_i2s = devm_clk_get(dev, "i2s"); if (IS_ERR(i2s->clk_i2s)) return PTR_ERR(i2s->clk_i2s); platform_set_drvdata(pdev, i2s); - if (i2s->version == JZ_I2S_JZ4780) - ret = devm_snd_soc_register_component(&pdev->dev, - &jz4740_i2s_component, &jz4780_i2s_dai, 1); - else - ret = devm_snd_soc_register_component(&pdev->dev, - &jz4740_i2s_component, &jz4740_i2s_dai, 1); - + ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component, + i2s->soc_info->dai, 1); if (ret) return ret; - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, + return devm_snd_dmaengine_pcm_register(dev, NULL, SND_DMAENGINE_PCM_FLAG_COMPAT); } @@ -555,7 +589,7 @@ .probe = jz4740_i2s_dev_probe, .driver = { .name = "jz4740-i2s", - .of_match_table = of_match_ptr(jz4740_of_matches) + .of_match_table = jz4740_of_matches, }, }; -- Gitblit v1.6.2