^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Socionext UniPhier AIO ALSA CPU DAI driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2016-2018 Socionext Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "aio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static bool is_valid_pll(struct uniphier_aio_chip *chip, int pll_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct device *dev = &chip->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (pll_id < 0 || chip->num_plls <= pll_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) dev_err(dev, "PLL(%d) is not supported\n", pll_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return chip->plls[pll_id].enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * find_volume - find volume supported HW port by HW port number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @chip: the AIO chip pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @oport_hw: HW port number, one of AUD_HW_XXXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * Find AIO device from device list by HW port number. Volume feature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * available only in Output and PCM ports, this limitation comes from HW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * specifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * Return: The pointer of AIO substream if successful, otherwise NULL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static struct uniphier_aio_sub *find_volume(struct uniphier_aio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int oport_hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) for (i = 0; i < chip->num_aios; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct uniphier_aio_sub *sub = &chip->aios[i].sub[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!sub->swm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (sub->swm->oport.hw == oport_hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static bool match_spec(const struct uniphier_aio_spec *spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const char *name, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (dir == SNDRV_PCM_STREAM_PLAYBACK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spec->swm.dir != PORT_DIR_OUTPUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (dir == SNDRV_PCM_STREAM_CAPTURE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) spec->swm.dir != PORT_DIR_INPUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (spec->name && strcmp(spec->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (spec->gname && strcmp(spec->gname, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * find_spec - find HW specification info by name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * @aio: the AIO device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @name: name of device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @direction: the direction of substream, SNDRV_PCM_STREAM_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Find hardware specification information from list by device name. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * information is used for telling the difference of SoCs to driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * Specification list is array of 'struct uniphier_aio_spec' which is defined
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * in each drivers (see: aio-i2s.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Return: The pointer of hardware specification of AIO if successful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * otherwise NULL on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) const struct uniphier_aio_chip_spec *chip_spec = aio->chip->chip_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) for (i = 0; i < chip_spec->num_specs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) const struct uniphier_aio_spec *spec = &chip_spec->specs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (match_spec(spec, name, direction))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * find_divider - find clock divider by frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @aio: the AIO device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @pll_id: PLL ID, should be AUD_PLL_XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @freq: required frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * Find suitable clock divider by frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Return: The ID of PLL if successful, otherwise negative error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct uniphier_aio_pll *pll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int mul[] = { 1, 1, 1, 2, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) int div[] = { 2, 3, 1, 3, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!is_valid_pll(aio->chip, pll_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) pll = &aio->chip->plls[pll_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) for (i = 0; i < ARRAY_SIZE(mul); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (pll->freq * mul[i] / div[i] == freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int uniphier_aio_set_sysclk(struct snd_soc_dai *dai, int clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned int freq, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct device *dev = &aio->chip->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) bool pll_auto = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int pll_id, div_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (clk_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case AUD_CLK_IO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case AUD_CLK_A1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pll_id = AUD_PLL_A1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) case AUD_CLK_F1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pll_id = AUD_PLL_F1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case AUD_CLK_A2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pll_id = AUD_PLL_A2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case AUD_CLK_F2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pll_id = AUD_PLL_F2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case AUD_CLK_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pll_id = AUD_PLL_A1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) pll_auto = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case AUD_CLK_F:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pll_id = AUD_PLL_F1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pll_auto = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case AUD_CLK_APLL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pll_id = AUD_PLL_APLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) case AUD_CLK_RX0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) pll_id = AUD_PLL_RX0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case AUD_CLK_USB0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) pll_id = AUD_PLL_USB0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case AUD_CLK_HSC0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) pll_id = AUD_PLL_HSC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_err(dev, "Sysclk(%d) is not supported\n", clk_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (pll_auto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) for (pll_id = 0; pll_id < aio->chip->num_plls; pll_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) div_id = find_divider(aio, pll_id, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (div_id >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) aio->plldiv = div_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (pll_id == aio->chip->num_plls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev_err(dev, "Sysclk frequency is not supported(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (dir == SND_SOC_CLOCK_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) aio->pll_out = pll_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) aio->pll_in = pll_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int source, unsigned int freq_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) unsigned int freq_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (!is_valid_pll(aio->chip, pll_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static int uniphier_aio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct device *dev = &aio->chip->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case SND_SOC_DAIFMT_LEFT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case SND_SOC_DAIFMT_RIGHT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case SND_SOC_DAIFMT_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) aio->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_err(dev, "Format is not supported(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) fmt & SND_SOC_DAIFMT_FORMAT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static int uniphier_aio_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) sub->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) sub->pass_through = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sub->use_mmap = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) ret = aio_init(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static void uniphier_aio_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) sub->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int uniphier_aio_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct device *dev = &aio->chip->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int freq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) switch (params_rate(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) case 24000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) freq = 12288000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case 22050:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) freq = 11289600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dev_err(dev, "Rate is not supported(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) params_rate(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = snd_soc_dai_set_sysclk(dai, AUD_CLK_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) freq, SND_SOC_CLOCK_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sub->params = *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) sub->setting = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) aio_port_reset(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) aio_port_set_volume(sub, sub->vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) aio_src_reset(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int uniphier_aio_hw_free(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) sub->setting = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static int uniphier_aio_prepare(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct uniphier_aio_sub *sub = &aio->sub[substream->stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = aio_port_set_param(sub, sub->pass_through, &sub->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ret = aio_src_set_param(sub, &sub->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) aio_port_set_enable(sub, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = aio_if_set_param(sub, sub->pass_through);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (sub->swm->type == PORT_TYPE_CONV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = aio_srcif_set_param(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = aio_srcch_set_param(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) aio_srcch_set_enable(sub, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) const struct snd_soc_dai_ops uniphier_aio_i2s_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .set_sysclk = uniphier_aio_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .set_pll = uniphier_aio_set_pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .set_fmt = uniphier_aio_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .startup = uniphier_aio_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .shutdown = uniphier_aio_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .hw_params = uniphier_aio_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .hw_free = uniphier_aio_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .prepare = uniphier_aio_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) EXPORT_SYMBOL_GPL(uniphier_aio_i2s_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) const struct snd_soc_dai_ops uniphier_aio_spdif_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .set_sysclk = uniphier_aio_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) .set_pll = uniphier_aio_set_pll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) .startup = uniphier_aio_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) .shutdown = uniphier_aio_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) .hw_params = uniphier_aio_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .hw_free = uniphier_aio_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .prepare = uniphier_aio_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) EXPORT_SYMBOL_GPL(uniphier_aio_spdif_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int uniphier_aio_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct uniphier_aio_sub *sub = &aio->sub[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) const struct uniphier_aio_spec *spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) spec = find_spec(aio, dai->name, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) sub->swm = &spec->swm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) sub->spec = spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) sub->vol = AUD_VOL_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) aio_iecout_set_enable(aio->chip, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) aio_chip_init(aio->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) aio->chip->active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) EXPORT_SYMBOL_GPL(uniphier_aio_dai_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int uniphier_aio_dai_remove(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) aio->chip->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) EXPORT_SYMBOL_GPL(uniphier_aio_dai_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static void uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!snd_soc_dai_active(dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) aio->chip->num_wup_aios--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (!aio->chip->num_wup_aios) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) reset_control_assert(aio->chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) clk_disable_unprepare(aio->chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int uniphier_aio_suspend(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct snd_soc_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) for_each_component_dais(component, dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) uniphier_aio_dai_suspend(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct uniphier_aio *aio = uniphier_priv(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!snd_soc_dai_active(dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!aio->chip->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (!aio->chip->num_wup_aios) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret = clk_prepare_enable(aio->chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ret = reset_control_deassert(aio->chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) goto err_out_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) aio_iecout_set_enable(aio->chip, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) aio_chip_init(aio->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) for (i = 0; i < ARRAY_SIZE(aio->sub); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct uniphier_aio_sub *sub = &aio->sub[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!sub->spec || !sub->substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ret = aio_init(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (!sub->setting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) aio_port_reset(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) aio_src_reset(sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) aio->chip->num_wup_aios++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) err_out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!aio->chip->num_wup_aios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) reset_control_assert(aio->chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) err_out_clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (!aio->chip->num_wup_aios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) clk_disable_unprepare(aio->chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int uniphier_aio_resume(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct snd_soc_dai *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) for_each_component_dais(component, dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ret |= uniphier_aio_dai_resume(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int uniphier_aio_vol_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) uinfo->value.integer.max = AUD_VOL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int uniphier_aio_vol_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct uniphier_aio_sub *sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int oport_hw = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) sub = find_volume(chip, oport_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (!sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ucontrol->value.integer.value[0] = sub->vol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static int uniphier_aio_vol_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct uniphier_aio_sub *sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int oport_hw = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) sub = find_volume(chip, oport_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (!sub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (sub->vol == ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) sub->vol = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) aio_port_set_volume(sub, sub->vol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static const struct snd_kcontrol_new uniphier_aio_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .name = "HPCMOUT1 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) .private_value = AUD_HW_HPCMOUT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .name = "PCMOUT1 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .private_value = AUD_HW_PCMOUT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .name = "PCMOUT2 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .private_value = AUD_HW_PCMOUT2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) .name = "PCMOUT3 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .private_value = AUD_HW_PCMOUT3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .name = "HIECOUT1 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .private_value = AUD_HW_HIECOUT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .name = "IECOUT1 Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) .info = uniphier_aio_vol_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) .get = uniphier_aio_vol_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) .put = uniphier_aio_vol_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) .private_value = AUD_HW_IECOUT1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static const struct snd_soc_component_driver uniphier_aio_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .name = "uniphier-aio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .controls = uniphier_aio_controls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .num_controls = ARRAY_SIZE(uniphier_aio_controls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .suspend = uniphier_aio_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .resume = uniphier_aio_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int uniphier_aio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct uniphier_aio_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int ret, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) chip->chip_spec = of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!chip->chip_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) chip->regmap_sg = syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) "socionext,syscon");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (IS_ERR(chip->regmap_sg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (PTR_ERR(chip->regmap_sg) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) chip->regmap_sg = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) chip->clk = devm_clk_get(dev, "aio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (IS_ERR(chip->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return PTR_ERR(chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) chip->rst = devm_reset_control_get_shared(dev, "aio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (IS_ERR(chip->rst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return PTR_ERR(chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) chip->num_aios = chip->chip_spec->num_dais;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) chip->num_wup_aios = chip->num_aios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) chip->aios = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) chip->num_aios, sizeof(struct uniphier_aio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (!chip->aios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) chip->num_plls = chip->chip_spec->num_plls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) chip->plls = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) chip->num_plls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) sizeof(struct uniphier_aio_pll),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!chip->plls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) memcpy(chip->plls, chip->chip_spec->plls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sizeof(struct uniphier_aio_pll) * chip->num_plls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) for (i = 0; i < chip->num_aios; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct uniphier_aio *aio = &chip->aios[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) aio->chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) aio->fmt = SND_SOC_DAIFMT_I2S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) for (j = 0; j < ARRAY_SIZE(aio->sub); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct uniphier_aio_sub *sub = &aio->sub[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sub->aio = aio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) spin_lock_init(&sub->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) chip->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) platform_set_drvdata(pdev, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ret = clk_prepare_enable(chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ret = reset_control_deassert(chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) goto err_out_clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ret = devm_snd_soc_register_component(dev, &uniphier_aio_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) chip->chip_spec->dais,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) chip->chip_spec->num_dais);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dev_err(dev, "Register component failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = uniphier_aiodma_soc_register_platform(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dev_err(dev, "Register platform failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) goto err_out_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) err_out_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) reset_control_assert(chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) err_out_clock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) clk_disable_unprepare(chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) EXPORT_SYMBOL_GPL(uniphier_aio_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) int uniphier_aio_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct uniphier_aio_chip *chip = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) reset_control_assert(chip->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) clk_disable_unprepare(chip->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) EXPORT_SYMBOL_GPL(uniphier_aio_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) MODULE_DESCRIPTION("UniPhier AIO CPU DAI driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) MODULE_LICENSE("GPL v2");