From 297b60346df8beafee954a0fd7c2d64f33f3b9bc Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Sat, 11 May 2024 01:44:05 +0000 Subject: [PATCH] rtl8211F_led_control --- kernel/drivers/gpio/gpio-stp-xway.c | 96 +++++++++++++++++++++++++++++++++-------------- 1 files changed, 67 insertions(+), 29 deletions(-) diff --git a/kernel/drivers/gpio/gpio-stp-xway.c b/kernel/drivers/gpio/gpio-stp-xway.c index 1997208..0ce1543 100644 --- a/kernel/drivers/gpio/gpio-stp-xway.c +++ b/kernel/drivers/gpio/gpio-stp-xway.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. * * Copyright (C) 2012 John Crispin <john@phrozen.org> - * */ #include <linux/slab.h> @@ -17,8 +14,6 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/err.h> - -#include <lantiq_soc.h> /* * The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a @@ -46,7 +41,10 @@ #define XWAY_STP_4HZ BIT(23) #define XWAY_STP_8HZ BIT(24) #define XWAY_STP_10HZ (BIT(24) | BIT(23)) -#define XWAY_STP_SPEED_MASK (0xf << 23) +#define XWAY_STP_SPEED_MASK (BIT(23) | BIT(24) | BIT(25) | BIT(26) | BIT(27)) + +#define XWAY_STP_FPIS_VALUE BIT(21) +#define XWAY_STP_FPIS_MASK (BIT(20) | BIT(21)) /* clock source for automatic update */ #define XWAY_STP_UPD_FPI BIT(31) @@ -59,7 +57,9 @@ /* 2 groups of 3 bits can be driven by the phys */ #define XWAY_STP_PHY_MASK 0x7 #define XWAY_STP_PHY1_SHIFT 27 -#define XWAY_STP_PHY2_SHIFT 15 +#define XWAY_STP_PHY2_SHIFT 3 +#define XWAY_STP_PHY3_SHIFT 6 +#define XWAY_STP_PHY4_SHIFT 15 /* STP has 3 groups of 8 bits */ #define XWAY_STP_GROUP0 BIT(0) @@ -74,8 +74,7 @@ #define xway_stp_r32(m, reg) __raw_readl(m + reg) #define xway_stp_w32(m, val, reg) __raw_writel(val, m + reg) #define xway_stp_w32_mask(m, clear, set, reg) \ - ltq_w32((ltq_r32(m + reg) & ~(clear)) | (set), \ - m + reg) + xway_stp_w32(m, (xway_stp_r32(m, reg) & ~(clear)) | (set), reg) struct xway_stp { struct gpio_chip gc; @@ -86,6 +85,8 @@ u8 dsl; /* the 2 LSBs can be driven by the dsl core */ u8 phy1; /* 3 bits can be driven by phy1 */ u8 phy2; /* 3 bits can be driven by phy2 */ + u8 phy3; /* 3 bits can be driven by phy3 */ + u8 phy4; /* 3 bits can be driven by phy4 */ u8 reserved; /* mask out the hw driven bits in gpio_request */ }; @@ -120,7 +121,8 @@ else chip->shadow &= ~BIT(gpio); xway_stp_w32(chip->virt, chip->shadow, XWAY_STP_CPU0); - xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0); + if (!chip->reserved) + xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0); } /** @@ -159,9 +161,9 @@ /** * xway_stp_hw_init() - Configure the STP unit and enable the clock gate - * @virt: pointer to the remapped register range + * @chip: Pointer to the xway_stp chip structure */ -static int xway_stp_hw_init(struct xway_stp *chip) +static void xway_stp_hw_init(struct xway_stp *chip) { /* sane defaults */ xway_stp_w32(chip->virt, 0, XWAY_STP_AR); @@ -194,23 +196,41 @@ chip->phy2 << XWAY_STP_PHY2_SHIFT, XWAY_STP_CON1); + if (of_machine_is_compatible("lantiq,grx390") + || of_machine_is_compatible("lantiq,ar10")) { + xway_stp_w32_mask(chip->virt, + XWAY_STP_PHY_MASK << XWAY_STP_PHY3_SHIFT, + chip->phy3 << XWAY_STP_PHY3_SHIFT, + XWAY_STP_CON1); + } + + if (of_machine_is_compatible("lantiq,grx390")) { + xway_stp_w32_mask(chip->virt, + XWAY_STP_PHY_MASK << XWAY_STP_PHY4_SHIFT, + chip->phy4 << XWAY_STP_PHY4_SHIFT, + XWAY_STP_CON1); + } + /* mask out the hw driven bits in gpio_request */ - chip->reserved = (chip->phy2 << 5) | (chip->phy1 << 2) | chip->dsl; + chip->reserved = (chip->phy4 << 11) | (chip->phy3 << 8) | (chip->phy2 << 5) + | (chip->phy1 << 2) | chip->dsl; /* * if we have pins that are driven by hw, we need to tell the stp what * clock to use as a timer. */ - if (chip->reserved) + if (chip->reserved) { xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK, XWAY_STP_UPD_FPI, XWAY_STP_CON1); - - return 0; + xway_stp_w32_mask(chip->virt, XWAY_STP_SPEED_MASK, + XWAY_STP_10HZ, XWAY_STP_CON1); + xway_stp_w32_mask(chip->virt, XWAY_STP_FPIS_MASK, + XWAY_STP_FPIS_VALUE, XWAY_STP_CON1); + } } static int xway_stp_probe(struct platform_device *pdev) { - struct resource *res; u32 shadow, groups, dsl, phy; struct xway_stp *chip; struct clk *clk; @@ -220,8 +240,7 @@ if (!chip) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - chip->virt = devm_ioremap_resource(&pdev->dev, res); + chip->virt = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(chip->virt)) return PTR_ERR(chip->virt); @@ -252,32 +271,51 @@ /* find out which gpios are controlled by the phys */ if (of_machine_is_compatible("lantiq,ar9") || of_machine_is_compatible("lantiq,gr9") || - of_machine_is_compatible("lantiq,vr9")) { + of_machine_is_compatible("lantiq,vr9") || + of_machine_is_compatible("lantiq,ar10") || + of_machine_is_compatible("lantiq,grx390")) { if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy1", &phy)) chip->phy1 = phy & XWAY_STP_PHY_MASK; if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy2", &phy)) chip->phy2 = phy & XWAY_STP_PHY_MASK; } + if (of_machine_is_compatible("lantiq,ar10") || + of_machine_is_compatible("lantiq,grx390")) { + if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy3", &phy)) + chip->phy3 = phy & XWAY_STP_PHY_MASK; + } + + if (of_machine_is_compatible("lantiq,grx390")) { + if (!of_property_read_u32(pdev->dev.of_node, "lantiq,phy4", &phy)) + chip->phy4 = phy & XWAY_STP_PHY_MASK; + } + /* check which edge trigger we should use, default to a falling edge */ if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL)) chip->edge = XWAY_STP_FALLING; - clk = clk_get(&pdev->dev, NULL); + clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "Failed to get clock\n"); return PTR_ERR(clk); } - clk_enable(clk); - ret = xway_stp_hw_init(chip); - if (!ret) - ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); + ret = clk_prepare_enable(clk); + if (ret) + return ret; - if (!ret) - dev_info(&pdev->dev, "Init done\n"); + xway_stp_hw_init(chip); - return ret; + ret = devm_gpiochip_add_data(&pdev->dev, &chip->gc, chip); + if (ret) { + clk_disable_unprepare(clk); + return ret; + } + + dev_info(&pdev->dev, "Init done\n"); + + return 0; } static const struct of_device_id xway_stp_match[] = { -- Gitblit v1.6.2