brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 2f3c9eb Raw
164 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for the ps-mode pin configuration.4 *5 * Copyright (c) 2021 Xilinx, Inc.6 */7 8#include <linux/delay.h>9#include <linux/err.h>10#include <linux/gpio/driver.h>11#include <linux/io.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/platform_device.h>15#include <linux/slab.h>16#include <linux/firmware/xlnx-zynqmp.h>17 18/* 4-bit boot mode pins */19#define MODE_PINS			420 21/**22 * modepin_gpio_get_value - Get the state of the specified pin of GPIO device23 * @chip:	gpio_chip instance to be worked on24 * @pin:	gpio pin number within the device25 *26 * This function reads the state of the specified pin of the GPIO device.27 *28 * Return: 0 if the pin is low, 1 if pin is high, -EINVAL wrong pin configured29 *         or error value.30 */31static int modepin_gpio_get_value(struct gpio_chip *chip, unsigned int pin)32{33	u32 regval = 0;34	int ret;35 36	ret = zynqmp_pm_bootmode_read(&regval);37	if (ret)38		return ret;39 40	/* When [0:3] corresponding bit is set, then read output bit [8:11],41	 * if the bit is clear then read input bit [4:7] for status or value.42	 */43	if (regval & BIT(pin))44		return !!(regval & BIT(pin + 8));45	else46		return !!(regval & BIT(pin + 4));47}48 49/**50 * modepin_gpio_set_value - Modify the state of the pin with specified value51 * @chip:	gpio_chip instance to be worked on52 * @pin:	gpio pin number within the device53 * @state:	value used to modify the state of the specified pin54 *55 * This function reads the state of the specified pin of the GPIO device, mask56 * with the capture state of GPIO pin, and update pin of GPIO device.57 *58 * Return:	None.59 */60static void modepin_gpio_set_value(struct gpio_chip *chip, unsigned int pin,61				   int state)62{63	u32 bootpin_val = 0;64	int ret;65 66	zynqmp_pm_bootmode_read(&bootpin_val);67 68	/* Configure pin as an output by set bit [0:3] */69	bootpin_val |= BIT(pin);70 71	if (state)72		bootpin_val |= BIT(pin + 8);73	else74		bootpin_val &= ~BIT(pin + 8);75 76	/* Configure bootpin value */77	ret = zynqmp_pm_bootmode_write(bootpin_val);78	if (ret)79		pr_err("modepin: set value error %d for pin %d\n", ret, pin);80}81 82/**83 * modepin_gpio_dir_in - Set the direction of the specified GPIO pin as input84 * @chip:	gpio_chip instance to be worked on85 * @pin:	gpio pin number within the device86 *87 * Return: 0 always88 */89static int modepin_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)90{91	return 0;92}93 94/**95 * modepin_gpio_dir_out - Set the direction of the specified GPIO pin as output96 * @chip:	gpio_chip instance to be worked on97 * @pin:	gpio pin number within the device98 * @state:	value to be written to specified pin99 *100 * Return: 0 always101 */102static int modepin_gpio_dir_out(struct gpio_chip *chip, unsigned int pin,103				int state)104{105	return 0;106}107 108/**109 * modepin_gpio_probe - Initialization method for modepin_gpio110 * @pdev:		platform device instance111 *112 * Return: 0 on success, negative error otherwise.113 */114static int modepin_gpio_probe(struct platform_device *pdev)115{116	struct gpio_chip *chip;117	int status;118 119	chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);120	if (!chip)121		return -ENOMEM;122 123	platform_set_drvdata(pdev, chip);124 125	/* configure the gpio chip */126	chip->base = -1;127	chip->ngpio = MODE_PINS;128	chip->owner = THIS_MODULE;129	chip->parent = &pdev->dev;130	chip->get = modepin_gpio_get_value;131	chip->set = modepin_gpio_set_value;132	chip->direction_input = modepin_gpio_dir_in;133	chip->direction_output = modepin_gpio_dir_out;134	chip->label = dev_name(&pdev->dev);135 136	/* modepin gpio registration */137	status = devm_gpiochip_add_data(&pdev->dev, chip, chip);138	if (status)139		return dev_err_probe(&pdev->dev, status,140			      "Failed to add GPIO chip\n");141 142	return status;143}144 145static const struct of_device_id modepin_platform_id[] = {146	{ .compatible = "xlnx,zynqmp-gpio-modepin", },147	{ }148};149MODULE_DEVICE_TABLE(of, modepin_platform_id);150 151static struct platform_driver modepin_platform_driver = {152	.driver = {153		.name = "modepin-gpio",154		.of_match_table = modepin_platform_id,155	},156	.probe = modepin_gpio_probe,157};158 159module_platform_driver(modepin_platform_driver);160 161MODULE_AUTHOR("Piyush Mehta <piyush.mehta@xilinx.com>");162MODULE_DESCRIPTION("ZynqMP Boot PS_MODE Configuration");163MODULE_LICENSE("GPL v2");164