Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");