Linux Audio

Check our new training course

Loading...
v3.5.6
 
  1/*
  2 * arch/arm/mach-dove/mpp.c
  3 *
  4 * MPP functions for Marvell Dove SoCs
  5 *
  6 * This file is licensed under the terms of the GNU General Public
  7 * License version 2.  This program is licensed "as is" without any
  8 * warranty of any kind, whether express or implied.
  9 */
 10
 11#include <linux/kernel.h>
 12#include <linux/gpio.h>
 13#include <linux/io.h>
 14#include <plat/mpp.h>
 15#include <mach/dove.h>
 
 16#include "mpp.h"
 17
 18struct dove_mpp_grp {
 19	int start;
 20	int end;
 21};
 22
 23/* Map a group to a range of GPIO pins in that group */
 24static const struct dove_mpp_grp dove_mpp_grp[] = {
 25	[MPP_24_39] = {
 26		.start	= 24,
 27		.end	= 39,
 28	},
 29	[MPP_40_45] = {
 30		.start	= 40,
 31		.end	= 45,
 32	},
 33	[MPP_46_51] = {
 34		.start	= 46,
 35		.end	= 51,
 36	},
 37	[MPP_58_61] = {
 38		.start	= 58,
 39		.end	= 61,
 40	},
 41	[MPP_62_63] = {
 42		.start	= 62,
 43		.end	= 63,
 44	},
 45};
 46
 47/* Enable gpio for a range of pins. mode should be a combination of
 48   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
 49static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
 50{
 51	int i;
 52
 53	for (i = start; i <= end; i++)
 54		orion_gpio_set_valid(i, gpio_mode);
 55}
 56
 57/* Dump all the extra MPP registers. The platform code will dump the
 58   registers for pins 0-23. */
 59static void __init dove_mpp_dump_regs(void)
 60{
 61	pr_debug("PMU_CTRL4_CTRL: %08x\n",
 62		 readl(DOVE_MPP_CTRL4_VIRT_BASE));
 63
 64	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
 65		 readl(DOVE_PMU_MPP_GENERAL_CTRL));
 66
 67	pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
 68}
 69
 70static void __init dove_mpp_cfg_nfc(int sel)
 71{
 72	u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 73
 74	mpp_gen_cfg &= ~0x1;
 75	mpp_gen_cfg |= sel;
 76	writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
 77
 78	dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
 79}
 80
 81static void __init dove_mpp_cfg_au1(int sel)
 82{
 83	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 84	u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
 85	u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 86	u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
 87
 88	mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
 89	ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
 90	mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
 91	global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
 92
 93	if (!sel || sel == 0x2)
 94		dove_mpp_gpio_mode(52, 57, 0);
 95	else
 96		dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
 97
 98	if (sel & 0x1) {
 99		global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
100		dove_mpp_gpio_mode(56, 57, 0);
101	}
102	if (sel & 0x2) {
103		mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
104		dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
105	}
106	if (sel & 0x4) {
107		ssp_ctrl1 |= DOVE_SSP_ON_AU1;
108		dove_mpp_gpio_mode(52, 55, 0);
109	}
110	if (sel & 0x8)
111		mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
112
113	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
114	writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
115	writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
116	writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
117}
118
119/* Configure the group registers, enabling GPIO if sel indicates the
120   pin is to be used for GPIO */
121static void __init dove_mpp_conf_grp(unsigned int *mpp_grp_list)
122{
123	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
124	int gpio_mode;
125
126	for ( ; *mpp_grp_list; mpp_grp_list++) {
127		unsigned int num = MPP_NUM(*mpp_grp_list);
128		unsigned int sel = MPP_SEL(*mpp_grp_list);
129
130		if (num > MPP_GRP_MAX) {
131			pr_err("dove: invalid MPP GRP number (%u)\n", num);
132			continue;
133		}
134
135		mpp_ctrl4 &= ~(0x1 << num);
136		mpp_ctrl4 |= sel << num;
137
138		gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
139		dove_mpp_gpio_mode(dove_mpp_grp[num].start,
140				   dove_mpp_grp[num].end, gpio_mode);
141	}
142	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
143}
144
145/* Configure the various MPP pins on Dove */
146void __init dove_mpp_conf(unsigned int *mpp_list,
147			  unsigned int *mpp_grp_list,
148			  unsigned int grp_au1_52_57,
149			  unsigned int grp_nfc_64_71)
150{
151	dove_mpp_dump_regs();
152
153	/* Use platform code for pins 0-23 */
154	orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
155
156	dove_mpp_conf_grp(mpp_grp_list);
157	dove_mpp_cfg_au1(grp_au1_52_57);
158	dove_mpp_cfg_nfc(grp_nfc_64_71);
159
160	dove_mpp_dump_regs();
161}
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * arch/arm/mach-dove/mpp.c
  4 *
  5 * MPP functions for Marvell Dove SoCs
 
 
 
 
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/gpio.h>
 10#include <linux/io.h>
 11#include <plat/mpp.h>
 12#include <plat/orion-gpio.h>
 13#include "dove.h"
 14#include "mpp.h"
 15
 16struct dove_mpp_grp {
 17	int start;
 18	int end;
 19};
 20
 21/* Map a group to a range of GPIO pins in that group */
 22static const struct dove_mpp_grp dove_mpp_grp[] = {
 23	[MPP_24_39] = {
 24		.start	= 24,
 25		.end	= 39,
 26	},
 27	[MPP_40_45] = {
 28		.start	= 40,
 29		.end	= 45,
 30	},
 31	[MPP_46_51] = {
 32		.start	= 46,
 33		.end	= 51,
 34	},
 35	[MPP_58_61] = {
 36		.start	= 58,
 37		.end	= 61,
 38	},
 39	[MPP_62_63] = {
 40		.start	= 62,
 41		.end	= 63,
 42	},
 43};
 44
 45/* Enable gpio for a range of pins. mode should be a combination of
 46   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
 47static void __init dove_mpp_gpio_mode(int start, int end, int gpio_mode)
 48{
 49	int i;
 50
 51	for (i = start; i <= end; i++)
 52		orion_gpio_set_valid(i, gpio_mode);
 53}
 54
 55/* Dump all the extra MPP registers. The platform code will dump the
 56   registers for pins 0-23. */
 57static void __init dove_mpp_dump_regs(void)
 58{
 59	pr_debug("PMU_CTRL4_CTRL: %08x\n",
 60		 readl(DOVE_MPP_CTRL4_VIRT_BASE));
 61
 62	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
 63		 readl(DOVE_PMU_MPP_GENERAL_CTRL));
 64
 65	pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
 66}
 67
 68static void __init dove_mpp_cfg_nfc(int sel)
 69{
 70	u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 71
 72	mpp_gen_cfg &= ~0x1;
 73	mpp_gen_cfg |= sel;
 74	writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
 75
 76	dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
 77}
 78
 79static void __init dove_mpp_cfg_au1(int sel)
 80{
 81	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 82	u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
 83	u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 84	u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
 85
 86	mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
 87	ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
 88	mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
 89	global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
 90
 91	if (!sel || sel == 0x2)
 92		dove_mpp_gpio_mode(52, 57, 0);
 93	else
 94		dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
 95
 96	if (sel & 0x1) {
 97		global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
 98		dove_mpp_gpio_mode(56, 57, 0);
 99	}
100	if (sel & 0x2) {
101		mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
102		dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
103	}
104	if (sel & 0x4) {
105		ssp_ctrl1 |= DOVE_SSP_ON_AU1;
106		dove_mpp_gpio_mode(52, 55, 0);
107	}
108	if (sel & 0x8)
109		mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
110
111	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
112	writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
113	writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
114	writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
115}
116
117/* Configure the group registers, enabling GPIO if sel indicates the
118   pin is to be used for GPIO */
119static void __init dove_mpp_conf_grp(unsigned int *mpp_grp_list)
120{
121	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
122	int gpio_mode;
123
124	for ( ; *mpp_grp_list; mpp_grp_list++) {
125		unsigned int num = MPP_NUM(*mpp_grp_list);
126		unsigned int sel = MPP_SEL(*mpp_grp_list);
127
128		if (num > MPP_GRP_MAX) {
129			pr_err("dove: invalid MPP GRP number (%u)\n", num);
130			continue;
131		}
132
133		mpp_ctrl4 &= ~(0x1 << num);
134		mpp_ctrl4 |= sel << num;
135
136		gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
137		dove_mpp_gpio_mode(dove_mpp_grp[num].start,
138				   dove_mpp_grp[num].end, gpio_mode);
139	}
140	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
141}
142
143/* Configure the various MPP pins on Dove */
144void __init dove_mpp_conf(unsigned int *mpp_list,
145			  unsigned int *mpp_grp_list,
146			  unsigned int grp_au1_52_57,
147			  unsigned int grp_nfc_64_71)
148{
149	dove_mpp_dump_regs();
150
151	/* Use platform code for pins 0-23 */
152	orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
153
154	dove_mpp_conf_grp(mpp_grp_list);
155	dove_mpp_cfg_au1(grp_au1_52_57);
156	dove_mpp_cfg_nfc(grp_nfc_64_71);
157
158	dove_mpp_dump_regs();
159}