realtek: add RTL8231 chip detection
When initialising the driver, check if the RTL8231 chip is actually
present at the specified address. If the READY_CODE value does not match
the expected value, return -ENXIO to fail probing.
This should help users to figure out which address an RTL8231 is
configured to use, if measuring pull-up/-down resistors is not an
option.
On an unsuccesful probe, the driver will log:
    [    0.795364] Probing RTL8231 GPIOs
    [    0.798978] rtl8231_init called, MDIO bus ID: 30
    [    0.804194] rtl8231-gpio rtl8231-gpio: no device found at bus address 30
When a device is found, only the first two lines will be logged:
    [    0.453698] Probing RTL8231 GPIOs
    [    0.457312] rtl8231_init called, MDIO bus ID: 31
Signed-off-by: Sander Vanheule <sander@svanheule.net>
Tested-by: Stijn Tintel <stijn@linux-ipv6.be>
			
			
This commit is contained in:
		 Sander Vanheule
					Sander Vanheule
				
			
				
					committed by
					
						 Stijn Tintel
						Stijn Tintel
					
				
			
			
				
	
			
			
			 Stijn Tintel
						Stijn Tintel
					
				
			
						parent
						
							44f7cfd760
						
					
				
				
					commit
					a93dfff10e
				
			| @@ -8,6 +8,9 @@ | |||||||
|  |  | ||||||
| /* RTL8231 registers for LED control */ | /* RTL8231 registers for LED control */ | ||||||
| #define RTL8231_LED_FUNC0			0x0000 | #define RTL8231_LED_FUNC0			0x0000 | ||||||
|  | #define RTL8231_LED_FUNC1			0x0001 | ||||||
|  | #define RTL8231_READY_MASK			0x03f0 | ||||||
|  | #define RTL8231_READY_VALUE			0x0370 | ||||||
| #define RTL8231_GPIO_PIN_SEL(gpio)		((0x0002) + ((gpio) >> 4)) | #define RTL8231_GPIO_PIN_SEL(gpio)		((0x0002) + ((gpio) >> 4)) | ||||||
| #define RTL8231_GPIO_DIR(gpio)			((0x0005) + ((gpio) >> 4)) | #define RTL8231_GPIO_DIR(gpio)			((0x0005) + ((gpio) >> 4)) | ||||||
| #define RTL8231_GPIO_DATA(gpio)			((0x001C) + ((gpio) >> 4)) | #define RTL8231_GPIO_DATA(gpio)			((0x001C) + ((gpio) >> 4)) | ||||||
| @@ -238,6 +241,8 @@ void rtl8231_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) | |||||||
|  |  | ||||||
| int rtl8231_init(struct rtl8231_gpios *gpios) | int rtl8231_init(struct rtl8231_gpios *gpios) | ||||||
| { | { | ||||||
|  | 	u32 ret; | ||||||
|  |  | ||||||
| 	pr_info("%s called, MDIO bus ID: %d\n", __func__, gpios->smi_bus_id); | 	pr_info("%s called, MDIO bus ID: %d\n", __func__, gpios->smi_bus_id); | ||||||
|  |  | ||||||
| 	gpios->reg_cached = 0; | 	gpios->reg_cached = 0; | ||||||
| @@ -251,6 +256,10 @@ int rtl8231_init(struct rtl8231_gpios *gpios) | |||||||
| 		sw_w32_mask(3, 1, RTL838X_DMY_REG5); | 		sw_w32_mask(3, 1, RTL838X_DMY_REG5); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	ret = rtl8231_read(gpios, RTL8231_LED_FUNC1); | ||||||
|  | 	if ((ret & 0x80000000) || ((ret & RTL8231_READY_MASK) != RTL8231_READY_VALUE)) | ||||||
|  | 		return -ENXIO; | ||||||
|  |  | ||||||
| 	/* Select GPIO functionality and force input direction for pins 0-36 */ | 	/* Select GPIO functionality and force input direction for pins 0-36 */ | ||||||
| 	rtl8231_write(gpios, RTL8231_GPIO_PIN_SEL(0), 0xffff); | 	rtl8231_write(gpios, RTL8231_GPIO_PIN_SEL(0), 0xffff); | ||||||
| 	rtl8231_write(gpios, RTL8231_GPIO_DIR(0), 0xffff); | 	rtl8231_write(gpios, RTL8231_GPIO_DIR(0), 0xffff); | ||||||
| @@ -307,7 +316,11 @@ static int rtl8231_gpio_probe(struct platform_device *pdev) | |||||||
| 		return err; | 		return err; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	rtl8231_init(gpios); | 	err = rtl8231_init(gpios); | ||||||
|  | 	if (err) { | ||||||
|  | 		dev_err(dev, "no device found at bus address %d\n", gpios->smi_bus_id); | ||||||
|  | 		return err; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	gpios->dev = dev; | 	gpios->dev = dev; | ||||||
| 	gpios->gc.base = -1; | 	gpios->gc.base = -1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user