2022-05-09 03:28:58

by Gireesh.Hiremath

[permalink] [raw]
Subject: [PATCH v2 1/4] ARM: dts: am335x: Guardian: switch to AM33XX_PADCONF pinmux macro

From: Gireesh Hiremath <[email protected]>

switch the pin definitions from AM33XX_IOPAD to AM33XX_PADCONF macro

Signed-off-by: Gireesh Hiremath <[email protected]>
---

No changes since v1

arch/arm/boot/dts/am335x-guardian.dts | 229 +++++++++++++++-----------
1 file changed, 132 insertions(+), 97 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-guardian.dts b/arch/arm/boot/dts/am335x-guardian.dts
index 1a7e187b1953..94d9e51cd0f9 100644
--- a/arch/arm/boot/dts/am335x-guardian.dts
+++ b/arch/arm/boot/dts/am335x-guardian.dts
@@ -485,7 +485,7 @@
clkout2_pin: pinmux_clkout2_pin {
pinctrl-single,pins = <
/* xdma_event_intr1.clkout2 */
- AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
+ AM33XX_PADCONF(AM335X_PIN_XDMA_EVENT_INTR1, PIN_OUTPUT_PULLDOWN, MUX_MODE3)
>;
};

@@ -493,254 +493,289 @@
pinctrl-single,pins = <
/* ADC_BATSENSE_EN */
/* (A14) MCASP0_AHCLKx.gpio3[21] */
- AM33XX_IOPAD(0x9ac, PIN_OUTPUT_PULLDOWN | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_AHCLKX, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
/* ADC_COINCELL_EN */
/* (J16) MII1_TX_EN.gpio3[3] */
- AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_MII1_TX_EN, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
/* ASP_ENABLE */
/* (A13) MCASP0_ACLKx.gpio3[14] */
- AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_MCASP0_ACLKX, PIN_OUTPUT_PULLUP, MUX_MODE7)
/* (D16) uart1_rxd.uart1_rxd */
- AM33XX_IOPAD(0x980, PIN_INPUT | MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_UART1_RXD, PIN_INPUT, MUX_MODE7)
/* (D15) uart1_txd.uart1_txd */
- AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_UART1_TXD, PIN_INPUT, MUX_MODE7)
/*SWITCH-OFF_3V6*/
/* (M18) gpio0[1] */
- AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_MDC, PIN_OUTPUT_PULLUP, MUX_MODE7)
/* MIRACULIX */
/* (H17) gmii1_crs.gpio3[1] */
- AM33XX_IOPAD(0x90c, PIN_OUTPUT_PULLDOWN | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_MII1_CRS, PIN_OUTPUT_PULLDOWN, MUX_MODE7 )
/* (H18) rmii1_refclk.gpio0[29] */
- AM33XX_IOPAD(0x944, PIN_OUTPUT_PULLDOWN | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_RMII1_REF_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
/* (J18) gmii1_txd3.gpio0[16] */
- AM33XX_IOPAD(0x91c, PIN_INPUT | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_MII1_TXD3, PIN_INPUT, MUX_MODE7)
/* (J17) gmii1_rxdv.gpio3[4] */
- AM33XX_IOPAD(0x918, PIN_OUTPUT_PULLDOWN | MUX_MODE7 )
+ AM33XX_PADCONF(AM335X_PIN_MII1_RX_DV, PIN_OUTPUT_PULLDOWN, MUX_MODE7)
>;
};

guardian_beeper_pins: pinmux_dmtimer7_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x968, PIN_OUTPUT | MUX_MODE5) /* (E18) timer7 */
+ /* (E18) timer7 */
+ AM33XX_PADCONF(AM335X_PIN_UART0_CTSN, PIN_OUTPUT, MUX_MODE5)
>;
};

guardian_button_pins: pinmux_guardian_button_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x940, PIN_INPUT | MUX_MODE7) /* (M16) gmii1_rxd0.gpio2[21] */
- AM33XX_IOPAD(0x884, PIN_INPUT | MUX_MODE7) /* (V9) gpmc_csn2.gpio1[31] */
+ /* (M16) gmii1_rxd0.gpio2[21] */
+ AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_INPUT, MUX_MODE7)
+ /* (V9) gpmc_csn2.gpio1[31] */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN2, PIN_INPUT, MUX_MODE7)
>;
};


i2c0_pins: pinmux_i2c0_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
- AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ /* i2c0_sda.i2c0_sda */
+ AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* i2c0_scl.i2c0_scl */
+ AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_INPUT_PULLUP, MUX_MODE0)
>;
};

led_bl_pins: gpio_led_bl_pins {
pinctrl-single,pins = <
/* P9_14, gpmc_a[2].GPIO1[18] (backlight control) */
- AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE7)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_A2, PIN_OUTPUT, MUX_MODE7)
>;
};

lcd_disen_pins: pinmux_lcd_disen_pins {
pinctrl-single,pins = <
/* P9_27, mcasp0_fsr.gpio3[19] (lcd_disen) */
- AM33XX_IOPAD(0x9a4, PIN_OUTPUT_PULLUP | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_MCASP0_FSR, PIN_OUTPUT_PULLUP | SLEWCTRL_SLOW, MUX_MODE7)
>;
};

lcd_pins_default: pinmux_lcd_pins_default {
pinctrl-single,pins = <
/* (U10) gpmc_ad8.lcd_data23 */
- AM33XX_IOPAD(0x820, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD8, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (T10) gpmc_ad9.lcd_data22 */
- AM33XX_IOPAD(0x824, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD9, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (T11) gpmc_ad10.lcd_data21 */
- AM33XX_IOPAD(0x828, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD10, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (U12) gpmc_ad11.lcd_data20 */
- AM33XX_IOPAD(0x82c, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD11, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (T12) gpmc_ad12.lcd_data19 */
- AM33XX_IOPAD(0x830, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD12, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (R12) gpmc_ad13.lcd_data18 */
- AM33XX_IOPAD(0x834, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD13, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (V13) gpmc_ad14.lcd_data17 */
- AM33XX_IOPAD(0x838, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD14, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* (U13) gpmc_ad15.lcd_data16 */
- AM33XX_IOPAD(0x83c, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD15, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE1)
/* lcd_data0.lcd_data0 */
- AM33XX_IOPAD(0x8a0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA0, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data1.lcd_data1 */
- AM33XX_IOPAD(0x8a4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA1, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data2.lcd_data2 */
- AM33XX_IOPAD(0x8a8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA2, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data3.lcd_data3 */
- AM33XX_IOPAD(0x8ac, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA3, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data4.lcd_data4 */
- AM33XX_IOPAD(0x8b0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA4, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data5.lcd_data5 */
- AM33XX_IOPAD(0x8b4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA5, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data6.lcd_data6 */
- AM33XX_IOPAD(0x8b8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA6, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data7.lcd_data7 */
- AM33XX_IOPAD(0x8bc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA7, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data8.lcd_data8 */
- AM33XX_IOPAD(0x8c0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA8, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data9.lcd_data9 */
- AM33XX_IOPAD(0x8c4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA9, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data10.lcd_data10 */
- AM33XX_IOPAD(0x8c8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA10, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data11.lcd_data11 */
- AM33XX_IOPAD(0x8cc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA11, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data12.lcd_data12 */
- AM33XX_IOPAD(0x8d0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA12, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data13.lcd_data13 */
- AM33XX_IOPAD(0x8d4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA13, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data14.lcd_data14 */
- AM33XX_IOPAD(0x8d8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA14, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_data15.lcd_data15 */
- AM33XX_IOPAD(0x8dc, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_DATA15, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_vsync.lcd_vsync */
- AM33XX_IOPAD(0x8e0, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_VSYNC, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_hsync.lcd_hsync */
- AM33XX_IOPAD(0x8e4, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_HSYNC, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_pclk.lcd_pclk */
- AM33XX_IOPAD(0x8e8, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_LCD_PCLK, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
/* lcd_ac_bias_en.lcd_ac_bias_en */
- AM33XX_IOPAD(0x8ec, PIN_OUTPUT | SLEWCTRL_SLOW | MUX_MODE0)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_AC_BIAS_EN, PIN_OUTPUT | SLEWCTRL_SLOW, MUX_MODE0)
>;
};

lcd_pins_sleep: pinmux_lcd_pins_sleep {
pinctrl-single,pins = <
/* lcd_data0.lcd_data0 */
- AM33XX_IOPAD(0x8a0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA0, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data1.lcd_data1 */
- AM33XX_IOPAD(0x8a4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA1, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data2.lcd_data2 */
- AM33XX_IOPAD(0x8a8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA2, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data3.lcd_data3 */
- AM33XX_IOPAD(0x8ac, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA3, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data4.lcd_data4 */
- AM33XX_IOPAD(0x8b0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA4, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data5.lcd_data5 */
- AM33XX_IOPAD(0x8b4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA5, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data6.lcd_data6 */
- AM33XX_IOPAD(0x8b8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA6, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data7.lcd_data7 */
- AM33XX_IOPAD(0x8bc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA7, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data8.lcd_data8 */
- AM33XX_IOPAD(0x8c0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA8, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data9.lcd_data9 */
- AM33XX_IOPAD(0x8c4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA9, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data10.lcd_data10 */
- AM33XX_IOPAD(0x8c8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA10, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data11.lcd_data11 */
- AM33XX_IOPAD(0x8cc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA11, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data12.lcd_data12 */
- AM33XX_IOPAD(0x8d0, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA12, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data13.lcd_data13 */
- AM33XX_IOPAD(0x8d4, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA13, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data14.lcd_data14 */
- AM33XX_IOPAD(0x8d8, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA14, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_data15.lcd_data15 */
- AM33XX_IOPAD(0x8dc, PULL_DISABLE | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_DATA15, PULL_DISABLE | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_vsync.lcd_vsync */
- AM33XX_IOPAD(0x8e0, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_VSYNC, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_hsync.lcd_hsync */
- AM33XX_IOPAD(0x8e4, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_HSYNC, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_pclk.lcd_pclk */
- AM33XX_IOPAD(0x8e8, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_PCLK, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW, MUX_MODE7)
/* lcd_ac_bias_en.lcd_ac_bias_en */
- AM33XX_IOPAD(0x8ec, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW | MUX_MODE7)
+ AM33XX_PADCONF
+ (AM335X_PIN_LCD_AC_BIAS_EN, PIN_INPUT_PULLDOWN | SLEWCTRL_SLOW, MUX_MODE7)
>;
};

guardian_led_pins: pinmux_guardian_led_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x868, PIN_OUTPUT | MUX_MODE7) /* (T16) gpmc_a10.gpio1[26] */
+ /* (T16) gpmc_a10.gpio1[26] */
+ AM33XX_PADCONF(AM335X_PIN_GPMC_A10, PIN_OUTPUT, MUX_MODE7)
>;
};

mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
- AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat3.mmc0_dat3 */
- AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat2.mmc0_dat2 */
- AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat1.mmc0_dat1 */
- AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_dat0.mmc0_dat0 */
- AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_clk.mmc0_clk */
- AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc0_cmd.mmc0_cmd */
- AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7) /* GPIO0_6 */
+ /* mmc0_dat3.mmc0_dat3 */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_DAT3, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* mmc0_dat2.mmc0_dat2 */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_DAT2, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* mmc0_dat1.mmc0_dat1 */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_DAT1, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* mmc0_dat0.mmc0_dat0 */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_DAT0, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* mmc0_clk.mmc0_clk */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_CLK, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* mmc0_cmd.mmc0_cmd */
+ AM33XX_PADCONF(AM335X_PIN_MMC0_CMD, PIN_INPUT_PULLUP, MUX_MODE0)
+ /* GPIO0_6 */
+ AM33XX_PADCONF(AM335X_PIN_SPI0_CS1, PIN_INPUT, MUX_MODE7)
>;
};

spi0_pins: pinmux_spi0_pins {
pinctrl-single,pins = <
/* SPI0_CLK - spi0_clk.spi */
- AM33XX_IOPAD(0x950, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_SPI0_SCLK, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
/* SPI0_MOSI - spi0_d0.spi0 */
- AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_SPI0_D0, PIN_OUTPUT_PULLUP, MUX_MODE0)
/* SPI0_MISO - spi0_d1.spi0 */
- AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_SPI0_D1, PIN_INPUT_PULLUP, MUX_MODE0)
/* SPI0_CS0 - spi */
- AM33XX_IOPAD(0x95c, PIN_OUTPUT_PULLUP | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_SPI0_CS0, PIN_OUTPUT_PULLUP, MUX_MODE0)
>;
};

uart0_pins: pinmux_uart0_pins {
pinctrl-single,pins = <
/* uart0_rxd.uart0_rxd */
- AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_UART0_RXD, PIN_INPUT_PULLUP, MUX_MODE0)
/* uart0_txd.uart0_txd */
- AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_UART0_TXD, PIN_OUTPUT_PULLDOWN, MUX_MODE0)
>;
};

uart2_pins: pinmux_uart2_pins {
pinctrl-single,pins = <
/* K18 uart2_rxd.mirx_txd */
- AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_MII1_TX_CLK, PIN_INPUT_PULLUP, MUX_MODE1)
/* L18 uart2_txd.mirx_rxd */
- AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLDOWN | MUX_MODE1)
+ AM33XX_PADCONF(AM335X_PIN_MII1_RX_CLK, PIN_OUTPUT_PULLDOWN, MUX_MODE1)
>;
};

nandflash_pins: pinmux_nandflash_pins {
pinctrl-single,pins = <
/* (U7) gpmc_ad0.gpmc_ad0 */
- AM33XX_IOPAD(0x800, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD0, PIN_INPUT, MUX_MODE0)
/* (V7) gpmc_ad1.gpmc_ad1 */
- AM33XX_IOPAD(0x804, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD1, PIN_INPUT, MUX_MODE0)
/* (R8) gpmc_ad2.gpmc_ad2 */
- AM33XX_IOPAD(0x808, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD2, PIN_INPUT, MUX_MODE0)
/* (T8) gpmc_ad3.gpmc_ad3 */
- AM33XX_IOPAD(0x80c, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD3, PIN_INPUT, MUX_MODE0)
/* (U8) gpmc_ad4.gpmc_ad4 */
- AM33XX_IOPAD(0x810, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD4, PIN_INPUT, MUX_MODE0)
/* (V8) gpmc_ad5.gpmc_ad5 */
- AM33XX_IOPAD(0x814, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD5, PIN_INPUT, MUX_MODE0)
/* (R9) gpmc_ad6.gpmc_ad6 */
- AM33XX_IOPAD(0x818, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD6, PIN_INPUT, MUX_MODE0)
/* (T9) gpmc_ad7.gpmc_ad7 */
- AM33XX_IOPAD(0x81c, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_AD7, PIN_INPUT, MUX_MODE0)
/* (T17) gpmc_wait0.gpmc_wait0 */
- AM33XX_IOPAD(0x870, PIN_INPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_WAIT0, PIN_INPUT, MUX_MODE0)
/* (U17) gpmc_wpn.gpmc_wpn */
- AM33XX_IOPAD(0x874, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_WPN, PIN_OUTPUT, MUX_MODE0)
/* (V6) gpmc_csn0.gpmc_csn0 */
- AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_CSN0, PIN_OUTPUT, MUX_MODE0)
/* (R7) gpmc_advn_ale.gpmc_advn_ale */
- AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_ADVN_ALE, PIN_OUTPUT, MUX_MODE0)
/* (T7) gpmc_oen_ren.gpmc_oen_ren */
- AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_OEN_REN, PIN_OUTPUT, MUX_MODE0)
/* (U6) gpmc_wen.gpmc_wen */
- AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_WEN, PIN_OUTPUT, MUX_MODE0)
/* (T6) gpmc_be0n_cle.gpmc_be0n_cle */
- AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0)
+ AM33XX_PADCONF(AM335X_PIN_GPMC_BEN0_CLE, PIN_OUTPUT, MUX_MODE0)
>;
};
};
--
2.20.1



2022-05-09 07:05:23

by Gireesh.Hiremath

[permalink] [raw]
Subject: [PATCH v2 2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

From: Gireesh Hiremath <[email protected]>

add support for keypad driver running on Bosch Guardian
Dtect board using TI-am335x cpu. Driver implementation
is based on matrix_keypad.c

Signed-off-by: Gireesh Hiremath <[email protected]>
---
Hi Marco,

Changes since v1: resolved compilation warnings

>On 22-05-04, [email protected] wrote:
>> From: Gireesh Hiremath <[email protected]>
>>
>> The existing matric_keypad.c use different gpio line for row and colunm,
>> where in mt_matrix_kepad.c use same gpio line for row as well as column.
>> a key can be placed at each intersection of a unique row number
>> not equal to a unique column and they are diagonally symmetric.
>> Advantage of this is with existed gpio line we can get more keys
>>
>> example: in matrix_keypad.c for 5 gpio line possible matrix is 2X3 or 3X2
>> and maximum possible keys are 6 but
>> in mt_matrix_kepad.c for same 5 gpio line possible matrix is 5X5 and maximum
>> possible buttons are 10, below table will discribe that
>
>Nobody should stop you to increase the amount of max. possible keys, so
>this isn't a real block.
>> ------------------------------------------------------
>> |Row\Col |GPIO 0 | GPIO 1 | GPIO 2 | GPIO 3 | GPIO 4 |
>> ------------------------------------------------------
>> | GPIO 0 | X | KEY_9 | KEY_2 | KEY_3 | KEY_1 |
>> ------------------------------------------------------
>> | GPIO 1 | KEY_9 | X | KEY_6 | KEY_5 | KEY_0 |
>> ------------------------------------------------------
>> | GPIO 2 | KEY_2 | KEY_6 | X | KEY_4 | KEY_7 |
>> ------------------------------------------------------
>> | GPIO 3 | KEY_3 | KEY_5 | KEY_4 | X | KEY_8 |
>> ------------------------------------------------------
>> | GPIO 4 | KEY_1 | KEY_0 | KEY_7 | KEY_8 | X |
>> ------------------------------------------------------
>> X - invalid key
>> KEY_x - preferred key code
>
>That should be pointed somewhere very clearly, thanks for the
>description. Also what is than the benefit of the original matrix_keypad
>driver?

we have special keypad for Bosch measuring tools, which is not completely
matric keypad so we have derived from matrix_kepad.c to make our keypad
to work.

In this keypad there may or may not have keymap for all gpio line
as below

------------------------------------------------------
|Row\Col |GPIO 0 | GPIO 1 | GPIO 2 | GPIO 3 | GPIO 4 |
------------------------------------------------------
| GPIO 0 | X | KEY_9 | KEY_2 | X | KEY_1 |
------------------------------------------------------
| GPIO 1 | KEY_9 | X | KEY_6 | X | X |
------------------------------------------------------
| GPIO 2 | KEY_2 | KEY_6 | X | KEY_4 | KEY_7 |
------------------------------------------------------
| GPIO 3 | X | X | KEY_4 | X | KEY_8 |
------------------------------------------------------
| GPIO 4 | KEY_1 | X | KEY_7 | KEY_8 | X |
------------------------------------------------------
X - invalid key

example DTS

line-gpios = <
&gpio1 24 1 /*gpio_56*/
&gpio1 23 1 /*gpio_55*/
&gpio1 22 1 /*gpio_54*/
&gpio1 20 1 /*gpio_52*/
&gpio1 16 1 /*gpio_48*/
>;
linux,keymap = <
0x00000000 /* row 0, col 0, KEY_RESERVED */
0x0001000a /* row 0, col 1, KEY_9 */
0x00020003 /* row 0, col 2, KEY_2 */
0x00030000 /* row 0, col 3, KEY_RESERVED */
0x00040002 /* row 0, col 4, KEY_1 */
0x0100000a /* row 1, col 0, KEY_9 */
0x01010000 /* row 1, col 1, KEY_RESERVED */
0x01020007 /* row 1, col 2, KEY_6 */
0x01030000 /* row 1, col 3, KEY_RESERVED */
0x01040000 /* row 1, col 4, KEY_RESERVED */
0x02000003 /* row 2, col 0, KEY_2 */
0x02010007 /* row 2, col 1, KEY_6 */
0x02020000 /* row 2, col 2, KEY_RESERVED */
0x02030005 /* row 2, col 3, KEY_4 */
0x02040008 /* row 2, col 4, KEY_7 */
0x03000000 /* row 3, col 0, KEY_RESERVED */
0x03010000 /* row 3, col 1, KEY_RESERVED */
0x03020005 /* row 3, col 2, KEY_4 */
0x03030000 /* row 3, col 3, KEY_RESERVED */
0x03040009 /* row 3, col 4, KEY_8 */
0x04000002 /* row 4, col 0, KEY_1 */
0x04010000 /* row 4, col 1, KEY_RESERVED */
0x04020008 /* row 4, col 2, KEY_7 */
0x04030009 /* row 4, col 3, KEY_8 */
0x04040000 /* row 4, col 4, KEY_RESERVED */
>;

>
>> both matric_keypad.c and mt_matrix_kepad.c logically operate differently,
>> my openion is not to merge both.
>
>IMHO from the user/system-integrator pov it is looking the same and so
>one driver should be fine. To distinguish between both modes we could
>add dt-property or add a new dt-compatible like "gpio-matrix-keypad-v2".
>

as mentioned above our keypad is not complete matrix keypad and it will
not be compatible with matrix_keypad diver. that is the reason we derived
mt matrix keypad driver.

to avoid confusion, we will rename the driver as bosch_mt_keypad.c
if you suggest.

>Regards,
> Marco

Regards
Gireesh Hiremath

drivers/input/keyboard/Kconfig | 10 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/mt_matrix_keypad.c | 741 ++++++++++++++++++++++
include/linux/input/mt_matrix_keypad.h | 85 +++
4 files changed, 837 insertions(+)
create mode 100644 drivers/input/keyboard/mt_matrix_keypad.c
create mode 100644 include/linux/input/mt_matrix_keypad.h

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 4ea79db8f134..a55ee8656194 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -303,6 +303,16 @@ config KEYBOARD_MATRIX
To compile this driver as a module, choose M here: the
module will be called matrix_keypad.

+config KEYBOARD_MT_MATRIX
+ tristate "GPIO driven MT matrix keypad support"
+ depends on GPIOLIB || COMPILE_TEST
+ help
+ This driver enable support for GPIO driven
+ mt matrix keypad.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mt_matrix_keypad.
+
config KEYBOARD_HIL_OLD
tristate "HP HIL keyboard support (simple driver)"
depends on GSC || HP300
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 721936e90290..c7686d338b5d 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o
obj-$(CONFIG_KEYBOARD_LPC32XX) += lpc32xx-keys.o
obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
+obj-$(CONFIG_KEYBOARD_MT_MATRIX) += mt_matrix_keypad.o
obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o
diff --git a/drivers/input/keyboard/mt_matrix_keypad.c b/drivers/input/keyboard/mt_matrix_keypad.c
new file mode 100644
index 000000000000..2664ce3c2653
--- /dev/null
+++ b/drivers/input/keyboard/mt_matrix_keypad.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * GPIO driven mt matrix keyboard driver
+ *
+ * Copyright (c) 2008 Marek Vasut <[email protected]>
+ * Copyright (c) 2017 vinay <[email protected]>
+ *
+ * Based on matrix_keypad.c
+ *
+ */
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/input/mt_matrix_keypad.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+
+#define MODULE_NAME "mt-matrix-keypad"
+
+struct mt_matrix_keypad {
+ struct mt_matrix_keypad_platform_data *pdata;
+ struct input_dev *input_dev;
+
+ DECLARE_BITMAP(disabled_gpios, MATRIX_MAX_ROWS);
+
+ struct delayed_work work;
+ spinlock_t lock;
+ bool scan_pending;
+ bool stopped;
+ bool gpio_all_disabled;
+};
+
+static bool
+get_gpio_line_value(const struct mt_matrix_keypad_platform_data *pdata,
+ int row);
+static void
+activate_line_driving(const struct mt_matrix_keypad_platform_data *pdata,
+ int line, bool on);
+
+void init_phase(struct mt_matrix_keypad_platform_data *pdata)
+{
+ pdata->phase_state.phase_prepare = -1;
+ pdata->phase_state.phase_start = 0;
+ pdata->phase_state.phase_update_button = pdata->num_line_gpios;
+}
+
+void button_init(struct button *btn, bool btn_hw_state, int key)
+{
+ btn->state.boPrevious = btn_hw_state;
+ btn->state.boCurrentStateOfHw = btn_hw_state;
+ btn->state.boCurrentStateOfSw = false;
+ btn->state.boCurrent = btn_hw_state;
+ btn->state.boEnabled = true;
+ btn->state.boStateAtInit = btn_hw_state;
+ btn->event.ui8Register = 0;
+ btn->key = key;
+}
+
+struct button_states get_button_state(struct button *btn)
+{
+ return btn->state;
+}
+
+union typeEvent get_and_clear_events(struct button *btn)
+{
+ union typeEvent beTemp = btn->event;
+
+ btn->event.ui8Register = 0;
+
+ return beTemp;
+}
+
+uint8_t get_btn_index(struct mt_matrix_keypad_platform_data *pdata, int btn_key)
+{
+ uint8_t i;
+
+ for (i = 0; i < pdata->num_of_buttons; i++) {
+ if (pdata->button_array[i].key == btn_key)
+ break;
+ }
+ return i;
+}
+
+void set_btn_state_by_hw(struct button *btn, bool boButtonState)
+{
+ btn->state.boCurrentStateOfHw = boButtonState;
+}
+
+bool check_button_changes(struct button *btn)
+{
+ btn->state.boPrevious = btn->state.boCurrent;
+ btn->state.boCurrent =
+ btn->state.boCurrentStateOfHw || btn->state.boCurrentStateOfSw;
+
+ /* Check if Button is pressed */
+ if ((btn->state.boPrevious == false) &&
+ (btn->state.boCurrent == true)) {
+ btn->event.status.boPressed = true;
+ }
+
+ /* Check if Button is released */
+ else if ((btn->state.boPrevious == true) &&
+ (btn->state.boCurrent == false)) {
+ btn->event.status.boReleased = true;
+ }
+
+ if (btn->event.ui8Register != 0)
+ btn->event.status.boGlobalChanged = true;
+
+ return btn->event.status.boGlobalChanged;
+}
+
+struct button_states
+get_btn_id_state(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index)
+{
+ if (btn_index < pdata->num_of_buttons)
+ return get_button_state(&pdata->button_array[btn_index]);
+ else
+ return get_button_state(&pdata->button_array[0]);
+}
+
+union typeEvent
+get_and_clear_btn_events(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index)
+{
+ if (btn_index < pdata->num_of_buttons)
+ return get_and_clear_events(&pdata->button_array[btn_index]);
+ else
+ return get_and_clear_events(&pdata->button_array[0]);
+}
+
+void button_hdl_init(struct mt_matrix_keypad_platform_data *pdata)
+{
+ int row, col, index;
+ int i;
+
+ pdata->scan_phase = pdata->phase_state.phase_prepare;
+ pdata->intialize_buttons = true;
+
+ /* Init Button Objects, will be reinited once states are captured */
+ i = 0;
+ for (row = 1; row < pdata->num_line_gpios; row++)
+ for (col = 0; col < row; col++) {
+ index = (row * pdata->num_line_gpios) + col;
+ if (pdata->button_matrix[index] !=
+ pdata->button_matrix[0]) {
+ if (i < pdata->num_of_buttons) {
+ button_init(
+ &pdata->button_array[i], false,
+ pdata->button_matrix[index]);
+ i++;
+ }
+ }
+ }
+
+ pr_debug("[%s]: %s Done\n", MODULE_NAME, __func__);
+}
+
+bool on_button_event(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index, union typeEvent btn_event,
+ struct input_dev *input_dev)
+{
+ bool any_btn_served = true;
+ unsigned int key_code = 0;
+ int key_value = 0;
+
+ key_code = pdata->button_array[btn_index].key;
+
+ if (btn_event.status.boPressed) {
+ key_value = 1;
+ pr_debug("[%s]:%d Pressed\n", MODULE_NAME, key_code);
+ }
+
+ if (btn_event.status.boReleased) {
+ key_value = 0;
+ pr_debug("[%s]:%d Released\n", MODULE_NAME, key_code);
+ }
+
+ input_report_key(input_dev, key_code, key_value);
+ input_sync(input_dev);
+ return any_btn_served;
+}
+
+void process_button_events(const struct mt_matrix_keypad_platform_data *pdata,
+ struct input_dev *input_dev)
+{
+ int btn_index;
+ bool any_btn_served = false;
+
+ for (btn_index = 0; btn_index < pdata->num_of_buttons; btn_index++) {
+ const union typeEvent beEvent =
+ get_and_clear_btn_events(pdata, (int)btn_index);
+
+ if (beEvent.status.boGlobalChanged) {
+ const struct button_states bsState =
+ get_btn_id_state(pdata, (int)btn_index);
+
+ if (bsState.boEnabled) {
+ any_btn_served |=
+ on_button_event(pdata, (int)btn_index,
+ beEvent, input_dev);
+ }
+ }
+ }
+}
+
+void update_buttons(struct mt_matrix_keypad_platform_data *pdata,
+ struct input_dev *input_dev)
+{
+ if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
+ pdata->scan_phase = pdata->phase_state.phase_start;
+ activate_line_driving(pdata, (int)pdata->scan_phase, true);
+ } else if (pdata->scan_phase ==
+ pdata->phase_state.phase_update_button) {
+ bool btn_changes_occured = false;
+ int btn_index;
+
+ if (pdata->intialize_buttons) {
+ int i;
+
+ pdata->intialize_buttons = false;
+
+ for (i = 0; i < pdata->num_of_buttons; i++) {
+ const bool btn_curr_hw_state =
+ get_button_state(
+ &pdata->button_array[i])
+ .boCurrentStateOfHw;
+ button_init(&pdata->button_array[i],
+ btn_curr_hw_state,
+ pdata->button_array[i].key);
+ }
+ }
+
+ for (btn_index = 0; btn_index < pdata->num_of_buttons;
+ btn_index++) {
+ btn_changes_occured |= check_button_changes(
+ &pdata->button_array[btn_index]);
+ }
+
+ if (btn_changes_occured)
+ process_button_events(pdata, input_dev);
+
+ pdata->scan_phase = pdata->phase_state.phase_start;
+ } else {
+ uint8_t *btn_keylines;
+ uint8_t number_of_buttons_pressed = 0;
+ uint8_t btn_index;
+ uint8_t btn_key;
+ uint16_t index;
+ int i;
+
+ btn_keylines = kcalloc(pdata->num_line_gpios, sizeof(uint8_t),
+ GFP_KERNEL);
+ for (i = 0; i < pdata->num_line_gpios; i++) {
+ index = (pdata->scan_phase * pdata->num_line_gpios) + i;
+ btn_key = pdata->button_matrix[index];
+ btn_keylines[i] = false;
+
+ if ((btn_key != pdata->button_matrix[0]) &&
+ (get_gpio_line_value(pdata, (int)i) != false)) {
+ btn_keylines[i] = true;
+ number_of_buttons_pressed++;
+ }
+ }
+ if (number_of_buttons_pressed < 2) {
+ for (i = 0; i < pdata->num_line_gpios; i++) {
+ index = (pdata->scan_phase *
+ pdata->num_line_gpios) +
+ i;
+ btn_key = pdata->button_matrix[index];
+ if (btn_key != pdata->button_matrix[0]) {
+ btn_index =
+ get_btn_index(pdata, btn_key);
+ set_btn_state_by_hw(
+ &pdata->button_array[btn_index],
+ btn_keylines[i]);
+ }
+ }
+ }
+
+ kfree(btn_keylines);
+ activate_line_driving(pdata, (int)pdata->scan_phase, false);
+ pdata->scan_phase++;
+ activate_line_driving(
+ pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
+ true);
+ }
+}
+
+/*
+ * NOTE: normally the GPIO has to be put into HiZ when de-activated to cause
+ * minmal side effect when scanning other columns, here it is configured to
+ * be input, and it should work on most platforms.
+ */
+static void
+__activate_line_driving(const struct mt_matrix_keypad_platform_data *pdata,
+ int line, bool on)
+{
+ bool level_on = pdata->active_low;
+
+ if (on)
+ gpio_direction_output(pdata->line_gpios[line], level_on);
+ else
+ gpio_direction_input(pdata->line_gpios[line]);
+}
+
+static void
+activate_line_driving(const struct mt_matrix_keypad_platform_data *pdata,
+ int line, bool on)
+{
+ __activate_line_driving(pdata, line, on);
+
+ if (on && pdata->col_scan_delay_us)
+ udelay(pdata->col_scan_delay_us);
+}
+
+static bool
+get_gpio_line_value(const struct mt_matrix_keypad_platform_data *pdata, int row)
+{
+ return gpio_get_value(pdata->line_gpios[row]) ? pdata->active_low :
+ !pdata->active_low;
+}
+
+/*
+ * This gets the keys from keyboard and reports it to input subsystem
+ */
+static void mt_matrix_keypad_scan(struct work_struct *work)
+{
+ struct mt_matrix_keypad *keypad =
+ container_of(work, struct mt_matrix_keypad, work.work);
+ struct input_dev *input_dev = keypad->input_dev;
+ struct mt_matrix_keypad_platform_data *pdata = keypad->pdata;
+
+ if (keypad->stopped == false) {
+ update_buttons(pdata, input_dev);
+ schedule_delayed_work(
+ &keypad->work,
+ msecs_to_jiffies(keypad->pdata->debounce_ms));
+ }
+}
+
+static int mt_matrix_keypad_start(struct input_dev *dev)
+{
+ struct mt_matrix_keypad *keypad = input_get_drvdata(dev);
+
+ keypad->stopped = false;
+ /*
+ * memory access initiated before the memory barrier
+ * will be complete before passing the barrier
+ */
+ mb();
+
+ /*
+ * Schedule an immediate key scan to capture current key state;
+ * columns will be activated and IRQs be enabled after the scan.
+ */
+ schedule_delayed_work(&keypad->work, 0);
+
+ return 0;
+}
+
+static void mt_matrix_keypad_stop(struct input_dev *dev)
+{
+ struct mt_matrix_keypad *keypad = input_get_drvdata(dev);
+
+ keypad->stopped = true;
+ /*
+ * memory access initiated before the memory barrier
+ * will be complete before passing the barrier
+ */
+ mb();
+ cancel_delayed_work_sync(&keypad->work);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void mt_matrix_keypad_enable_wakeup(struct mt_matrix_keypad *keypad)
+{
+ const struct mt_matrix_keypad_platform_data *pdata = keypad->pdata;
+ unsigned int gpio;
+ int i;
+
+ if (pdata->clustered_irq > 0) {
+ if (enable_irq_wake(pdata->clustered_irq) == 0)
+ keypad->gpio_all_disabled = true;
+ } else {
+ for (i = 0; i < pdata->num_line_gpios; i++) {
+ if (!test_bit(i, keypad->disabled_gpios)) {
+ gpio = pdata->line_gpios[i];
+
+ if (enable_irq_wake(gpio_to_irq(gpio)) == 0)
+ __set_bit(i, keypad->disabled_gpios);
+ }
+ }
+ }
+}
+
+static void mt_matrix_keypad_disable_wakeup(struct mt_matrix_keypad *keypad)
+{
+ const struct mt_matrix_keypad_platform_data *pdata = keypad->pdata;
+ unsigned int gpio;
+ int i;
+
+ if (pdata->clustered_irq > 0) {
+ if (keypad->gpio_all_disabled) {
+ disable_irq_wake(pdata->clustered_irq);
+ keypad->gpio_all_disabled = false;
+ }
+ } else {
+ for (i = 0; i < pdata->num_line_gpios; i++) {
+ if (test_and_clear_bit(i, keypad->disabled_gpios)) {
+ gpio = pdata->line_gpios[i];
+ disable_irq_wake(gpio_to_irq(gpio));
+ }
+ }
+ }
+}
+
+static int mt_matrix_keypad_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mt_matrix_keypad *keypad = platform_get_drvdata(pdev);
+
+ mt_matrix_keypad_stop(keypad->input_dev);
+
+ if (device_may_wakeup(&pdev->dev))
+ mt_matrix_keypad_enable_wakeup(keypad);
+
+ pinctrl_pm_select_sleep_state(dev);
+
+ return 0;
+}
+
+static int mt_matrix_keypad_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct mt_matrix_keypad *keypad = platform_get_drvdata(pdev);
+
+ if (device_may_wakeup(&pdev->dev))
+ mt_matrix_keypad_disable_wakeup(keypad);
+
+ pinctrl_pm_select_default_state(dev);
+
+ mt_matrix_keypad_start(keypad->input_dev);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mt_matrix_keypad_pm_ops, mt_matrix_keypad_suspend,
+ mt_matrix_keypad_resume);
+
+static int mt_matrix_keypad_init_gpio(struct platform_device *pdev,
+ struct mt_matrix_keypad *keypad)
+{
+ const struct mt_matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i, err;
+
+ for (i = 0; i < pdata->num_line_gpios; i++) {
+ err = gpio_request(pdata->line_gpios[i], "mt_kbd_row");
+ if (err) {
+ dev_err(&pdev->dev,
+ "failed to request GPIO%d for ROW%d\n",
+ pdata->line_gpios[i], i);
+ goto err_free_rows;
+ }
+
+ gpio_direction_input(pdata->line_gpios[i]);
+ }
+
+ return 0;
+
+err_free_rows:
+ while (--i >= 0)
+ gpio_free(pdata->line_gpios[i]);
+
+ i = pdata->num_line_gpios;
+ return err;
+}
+
+static void mt_matrix_keypad_free_gpio(struct mt_matrix_keypad *keypad)
+{
+ const struct mt_matrix_keypad_platform_data *pdata = keypad->pdata;
+ int i;
+
+ for (i = 0; i < pdata->num_line_gpios; i++)
+ gpio_free(pdata->line_gpios[i]);
+}
+
+#ifdef CONFIG_OF
+static struct mt_matrix_keypad_platform_data *
+mt_matrix_keypad_parse_dt(struct device *dev)
+{
+ struct mt_matrix_keypad_platform_data *pdata = NULL;
+ struct device_node *np = dev->of_node;
+ unsigned int *gpios;
+ struct button *button_array;
+ int8_t *button_matrix;
+ uint16_t keycode;
+ uint32_t *ptr;
+ int keymap;
+ int i;
+
+ if (!np) {
+ dev_err(dev, "device lacks DT data\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+
+ pdata->num_line_gpios = of_gpio_named_count(np, "line-gpios");
+ if (pdata->num_line_gpios <= 0) {
+ dev_err(dev, "number of gpio line not specified\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (of_get_property(np, "linux,no-autorepeat", NULL))
+ pdata->no_autorepeat = true;
+
+ pdata->wakeup = of_property_read_bool(np, "wakeup-source") ||
+ of_property_read_bool(np, "linux,wakeup"); /* legacy */
+
+ if (of_get_property(np, "gpio-activelow", NULL))
+ pdata->active_low = true;
+
+ of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
+ of_property_read_u32(np, "col-scan-delay-us",
+ &pdata->col_scan_delay_us);
+ of_property_read_u32(np, "number-of-buttons", &pdata->num_of_buttons);
+ if (pdata->num_of_buttons <= 0) {
+ dev_err(dev, "number of button not specified\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ button_array =
+ devm_kzalloc(dev,
+ sizeof(struct button) * (pdata->num_of_buttons),
+ GFP_KERNEL);
+ if (!button_array) {
+ dev_err(dev, "could not allocate memory for button array\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ pdata->button_array = button_array;
+
+ gpios = devm_kzalloc(dev,
+ sizeof(unsigned int) * (pdata->num_line_gpios),
+ GFP_KERNEL);
+ if (!gpios) {
+ dev_err(dev, "could not allocate memory for gpios\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ for (i = 0; i < pdata->num_line_gpios; i++)
+ gpios[i] = of_get_named_gpio(np, "line-gpios", i);
+
+ pdata->line_gpios = gpios;
+
+ keymap = device_property_count_u32(dev, "linux,keymap");
+ if (keymap <= 0 ||
+ keymap > (pdata->num_line_gpios * pdata->num_line_gpios)) {
+ dev_err(dev, "linux,keymap property count is more");
+ return ERR_PTR(-ENXIO);
+ }
+
+ ptr = kcalloc(keymap, sizeof(uint32_t), GFP_KERNEL);
+ if (!ptr)
+ return ERR_PTR(-ENOMEM);
+
+ if (device_property_read_u32_array(dev, "linux,keymap", ptr, keymap)) {
+ dev_err(dev, "problem parsing keymap property\n");
+ kfree(ptr);
+ return ERR_PTR(-EINVAL);
+ }
+
+ button_matrix =
+ devm_kzalloc(dev, (keymap * sizeof(int8_t)), GFP_KERNEL);
+ if (!button_matrix) {
+ dev_err(dev, "could not allocate memory for button matrix\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ pdata->button_matrix = button_matrix;
+ for (i = 0; i < keymap; i++) {
+ keycode = KEYCODE(ptr[i]);
+ pdata->button_matrix[i] = keycode;
+ }
+ kfree(ptr);
+
+ return pdata;
+}
+
+#else
+static inline struct mt_matrix_keypad_platform_data *
+mt_matrix_keypad_parse_dt(struct device *dev)
+{
+ dev_err(dev, "no platform data defined\n");
+
+ return ERR_PTR(-EINVAL);
+}
+#endif
+
+static int mt_matrix_keypad_probe(struct platform_device *pdev)
+{
+ struct mt_matrix_keypad_platform_data *pdata;
+ struct mt_matrix_keypad *keypad;
+ struct input_dev *input_dev;
+ int err;
+ int row, col, index;
+
+ dev_info(&pdev->dev, "[%s]: Probe\n", MODULE_NAME);
+ pdata = dev_get_platdata(&pdev->dev);
+
+ if (!pdata) {
+ pdata = mt_matrix_keypad_parse_dt(&pdev->dev);
+ if (IS_ERR(pdata)) {
+ dev_err(&pdev->dev, "Mt platform data not defined\n");
+ return PTR_ERR(pdata);
+ }
+ }
+
+ err = pdata->line_gpios[0];
+ if (err < 0)
+ return dev_err_probe(
+ &pdev->dev, err,
+ "Could not register gpio chip for mt matrix keypad\n");
+
+ keypad = kzalloc(sizeof(struct mt_matrix_keypad), GFP_KERNEL);
+ input_dev = input_allocate_device();
+
+ if (!keypad || !input_dev) {
+ dev_err(&pdev->dev, "[%s]: Allocation Failed\n", MODULE_NAME);
+ err = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ init_phase(pdata);
+ keypad->input_dev = input_dev;
+ keypad->pdata = pdata;
+ keypad->stopped = true;
+ INIT_DELAYED_WORK(&keypad->work, mt_matrix_keypad_scan);
+ spin_lock_init(&keypad->lock);
+
+ input_dev->name = pdev->name;
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->dev.parent = &pdev->dev;
+ input_dev->open = mt_matrix_keypad_start;
+ input_dev->close = mt_matrix_keypad_stop;
+
+ if (!pdata->no_autorepeat)
+ __set_bit(EV_REP, input_dev->evbit);
+
+ input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+ for (row = 1; row < pdata->num_line_gpios; row++) {
+ for (col = 0; col < row; col++) {
+ index = (row * pdata->num_line_gpios) + col;
+ if (pdata->button_matrix[index] !=
+ pdata->button_matrix[0]) {
+ input_set_capability(
+ input_dev, EV_KEY,
+ pdata->button_matrix[index]);
+ }
+ }
+ }
+
+ input_set_drvdata(input_dev, keypad);
+ err = mt_matrix_keypad_init_gpio(pdev, keypad);
+
+ if (err)
+ goto err_free_mem;
+
+ button_hdl_init(pdata);
+
+ err = input_register_device(keypad->input_dev);
+
+ if (err)
+ goto err_free_gpio;
+
+ device_init_wakeup(&pdev->dev, pdata->wakeup);
+ platform_set_drvdata(pdev, keypad);
+
+ return 0;
+
+err_free_gpio:
+ mt_matrix_keypad_free_gpio(keypad);
+
+err_free_mem:
+ input_free_device(input_dev);
+ kfree(keypad);
+ return err;
+}
+
+static int mt_matrix_keypad_remove(struct platform_device *pdev)
+{
+ struct mt_matrix_keypad *keypad = platform_get_drvdata(pdev);
+
+ device_init_wakeup(&pdev->dev, 0);
+ input_unregister_device(keypad->input_dev);
+ mt_matrix_keypad_free_gpio(keypad);
+ kfree(keypad);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id mt_matrix_keypad_dt_match[] = {
+ { .compatible = "gpio-mt-matrix-keypad" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, mt_matrix_keypad_dt_match);
+#endif
+
+static struct platform_driver mt_matrix_keypad_driver = {
+ .probe = mt_matrix_keypad_probe,
+ .remove = mt_matrix_keypad_remove,
+ .driver = {
+ .name = "mt-matrix-keypad",
+ .pm = &mt_matrix_keypad_pm_ops,
+ .of_match_table = of_match_ptr(mt_matrix_keypad_dt_match),
+ },
+};
+module_platform_driver(mt_matrix_keypad_driver);
+
+MODULE_AUTHOR("vinay");
+MODULE_DESCRIPTION("GPIO Driven Mt Matrix Keypad Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mt-matrix-keypad");
diff --git a/include/linux/input/mt_matrix_keypad.h b/include/linux/input/mt_matrix_keypad.h
new file mode 100644
index 000000000000..46dfe49c5fe1
--- /dev/null
+++ b/include/linux/input/mt_matrix_keypad.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _MT_MATRIX_KEYPAD_H
+#define _MT_MATRIX_KEYPAD_H
+
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/of.h>
+
+#define MATRIX_MAX_ROWS 32
+#define KEYCODE(keymap) (keymap & 0xFFFF)
+
+struct button_states {
+ uint8_t boPrevious : 1;
+ uint8_t boCurrent : 1;
+ uint8_t boCurrentStateOfHw : 1;
+ uint8_t boCurrentStateOfSw : 1;
+ uint8_t boEnabled : 1;
+ uint8_t boStateAtInit : 1;
+};
+
+union typeEvent {
+ uint8_t ui8Register;
+ struct {
+ uint8_t boGlobalChanged : 1;
+ uint8_t boPressed : 1;
+ uint8_t boReleased : 1;
+ } status;
+};
+
+struct button {
+ uint8_t key;
+ union typeEvent event;
+ struct button_states state;
+};
+
+struct phase {
+ int phase_prepare;
+ int phase_start;
+ int phase_update_button;
+};
+
+struct mt_matrix_keypad_platform_data {
+ const struct mt_keymap_data *keymap_data;
+ const unsigned int *line_gpios;
+ unsigned int num_line_gpios;
+ unsigned int num_of_buttons;
+ unsigned int col_scan_delay_us;
+ unsigned int debounce_ms;
+ unsigned int clustered_irq;
+ unsigned int clustered_irq_flags;
+
+ bool active_low;
+ bool wakeup;
+ bool no_autorepeat;
+ bool intialize_buttons;
+
+ int8_t scan_phase;
+ int8_t *button_matrix;
+ struct button *button_array;
+ struct phase phase_state;
+};
+
+void init_phase(struct mt_matrix_keypad_platform_data *pdata);
+void button_init(struct button *btn, bool btn_hw_state, int key);
+struct button_states get_button_state(struct button *btn);
+union typeEvent get_and_clear_events(struct button *btn);
+uint8_t get_btn_index(struct mt_matrix_keypad_platform_data *pdata,
+ int btn_key);
+void set_btn_state_by_hw(struct button *btn, bool boButtonState);
+bool check_button_changes(struct button *btn);
+struct button_states
+get_btn_id_state(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index);
+union typeEvent
+get_and_clear_btn_events(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index);
+void button_hdl_init(struct mt_matrix_keypad_platform_data *pdata);
+bool on_button_event(const struct mt_matrix_keypad_platform_data *pdata,
+ int btn_index, union typeEvent btn_event,
+ struct input_dev *input_dev);
+void process_button_events(const struct mt_matrix_keypad_platform_data *pdata,
+ struct input_dev *input_dev);
+void update_buttons(struct mt_matrix_keypad_platform_data *pdata,
+ struct input_dev *input_dev);
+#endif /* _MT_MATRIX_KEYPAD_H */
--
2.20.1


2022-05-10 20:40:12

by Gireesh.Hiremath

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

From: Gireesh Hiremath <[email protected]>

Hi Krzysztof,

>>>> both matric_keypad.c and mt_matrix_kepad.c logically operate differently,
>>>> my openion is not to merge both.
>>>
>>> IMHO from the user/system-integrator pov it is looking the same and so
>>> one driver should be fine. To distinguish between both modes we could
>>> add dt-property or add a new dt-compatible like "gpio-matrix-keypad-v2".
>>>
>>
>> as mentioned above our keypad is not complete matrix keypad and it will
>> not be compatible with matrix_keypad diver. that is the reason we derived
>> mt matrix keypad driver.
>>
>> to avoid confusion, we will rename the driver as bosch_mt_keypad.c
>> if you suggest.
>
>Sending a new version while discussions are ongoing is not how we reach
>consensus.

I apologize for sending new version.

>
>Make the driver as part of matrix-keypad driver or bring real arguments
>why it cannot be merged.

I tryied to put real hardware scenario which used in
Bosch Power tool measuring devices.
Keypad schematic as below, it is reduced matrix keypad compared
to standard matrix keypad

Pin8 (gpio1 16)-----------------------
Pin7 (gpio1 20)--------------------- |
Pin6 (gpio1 22)------------------- | |
Pin5 (gpio2 21)----------------- | | |
Pin4 (ground )--------------- | | | |
Pin3 (gpio1 31)------------- | | | | |
Pin2 (gpio1 23)----------- | | | | | |
Pin1 (gpio1 24)--------- | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
|------------|---------|----------------- | | | | | | |-----------|
| Button1 | | Button2 | | | | | | Button3 |
| _|_ | | _|_ | | | | | | _|_ |
| |--o o--| |--o o-----------| | | | | |------o o--|
| | | | | | | | |
| | |----------------------------| | | | | | |
| | Button4 | Button5 | | | | | Button6 |
| | _|_ | _|_ | | | | | _|_ |
| |--o o--| |---o o------------| | | | |---o o-----|
| | | | | | |
| | |------------------|---| | |-----------| |
| | | | | |
| |------------------------------| | |---------| | |
| | | | | |
| Button7 Button8 | | Button9 | | |
| _|_ _|_ | | _|_ | | |
|-----o o-----|--------o o----| |------o o----| | |
| | | |
| |---------------------------| |
| |
|-------------------------------------------------|


____________________________________
| Button | Pin activation| Keymap |
|----------------------------------|
|Button1 | 1,6 | KEY_7 |
|----------------------------------|
|Button2 | 1,2 | KEY_8 |
|----------------------------------|
|Button3 | 7,8 | KEY_9 |
|----------------------------------|
|Button4 | 2,6 | KEY_4 |
|----------------------------------|
|Button5 | 3,4 | KEY_5 |
|----------------------------------|
|Button6 | 6,7 | KEY_6 |
|----------------------------------|
|Button7 | 1,8 | KEY_1 |
|----------------------------------|
|Button8 | 6,8 | KEY_2 |
|----------------------------------|
|Button9 | 4,5 | KEY_3 |
|----------------------------------|

for Button5 and Button9 we used standard gpio_keys.c driver.

Button1,2,3,4,6,7,8 are not in standard row and column format,
found difficulty to apply matrix keypad drive to these button.

to solve this we came with vendor specific driver like
mt_matrix_keypad.c by taking matrix_keypad as reference.

after your review comment I felt it should named as
bosch_keypad.c to show as vendor specific.

in this driver all gpio lines act as row as well as column,
a key can be placed at each intersection of a unique row
number not equal to a unique column and they are diagonally
symmetric.
we can skip keymap for the valid intersection of gpio and
invalid keymap for row equal to column.

the matrix table as below for above schematic

------------------------------------------------------
|Row\Col |GPIO 0 | GPIO 1 | GPIO 2 | GPIO 3 | GPIO 4 |
------------------------------------------------------
| GPIO 0 | X | KEY_9 | KEY_2 | X | KEY_1 |
------------------------------------------------------
| GPIO 1 | KEY_9 | X | KEY_6 | X | X |
------------------------------------------------------
| GPIO 2 | KEY_2 | KEY_6 | X | KEY_4 | KEY_7 |
------------------------------------------------------
| GPIO 3 | X | X | KEY_4 | X | KEY_8 |
------------------------------------------------------
| GPIO 4 | KEY_1 | X | KEY_7 | KEY_8 | X |
------------------------------------------------------
X - invalid key
KEY_x - preferred key code


in Device tree we avoided row and column
and passed gpio info as line-gpios

line-gpios = <
&gpio1 24 1 /*gpio_56*/
&gpio1 23 1 /*gpio_55*/
&gpio1 22 1 /*gpio_54*/
&gpio1 20 1 /*gpio_52*/
&gpio1 16 1 /*gpio_48*/
>;
linux,keymap = <
0x00000000 /* row 0, col 0, KEY_RESERVED */
0x0001000a /* row 0, col 1, KEY_9 */
0x00020003 /* row 0, col 2, KEY_2 */
0x00030000 /* row 0, col 3, KEY_RESERVED */
0x00040002 /* row 0, col 4, KEY_1 */
0x0100000a /* row 1, col 0, KEY_9 */
0x01010000 /* row 1, col 1, KEY_RESERVED */
0x01020007 /* row 1, col 2, KEY_6 */
0x01030000 /* row 1, col 3, KEY_RESERVED */
0x01040000 /* row 1, col 4, KEY_RESERVED */
0x02000003 /* row 2, col 0, KEY_2 */
0x02010007 /* row 2, col 1, KEY_6 */
0x02020000 /* row 2, col 2, KEY_RESERVED */
0x02030005 /* row 2, col 3, KEY_4 */
0x02040008 /* row 2, col 4, KEY_7 */
0x03000000 /* row 3, col 0, KEY_RESERVED */
0x03010000 /* row 3, col 1, KEY_RESERVED */
0x03020005 /* row 3, col 2, KEY_4 */
0x03030000 /* row 3, col 3, KEY_RESERVED */
0x03040009 /* row 3, col 4, KEY_8 */
0x04000002 /* row 4, col 0, KEY_1 */
0x04010000 /* row 4, col 1, KEY_RESERVED */
0x04020008 /* row 4, col 2, KEY_7 */
0x04030009 /* row 4, col 3, KEY_8 */
0x04040000 /* row 4, col 4, KEY_RESERVED */
>;

this driver approch may be usefull for the embadded device
which are using reduced matrix keypad

>
>Best regards,
>Krzysztof

Best regards,
Gireesh Hiremath

2022-05-11 20:57:12

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

On 10/05/2022 16:13, [email protected] wrote:
> From: Gireesh Hiremath <[email protected]>
>
> Hi Krzysztof,
>
>>>>> both matric_keypad.c and mt_matrix_kepad.c logically operate differently,
>>>>> my openion is not to merge both.
>>>>
>>>> IMHO from the user/system-integrator pov it is looking the same and so
>>>> one driver should be fine. To distinguish between both modes we could
>>>> add dt-property or add a new dt-compatible like "gpio-matrix-keypad-v2".
>>>>
>>>
>>> as mentioned above our keypad is not complete matrix keypad and it will
>>> not be compatible with matrix_keypad diver. that is the reason we derived
>>> mt matrix keypad driver.
>>>
>>> to avoid confusion, we will rename the driver as bosch_mt_keypad.c
>>> if you suggest.
>>
>> Sending a new version while discussions are ongoing is not how we reach
>> consensus.
>
> I apologize for sending new version.
>
>>
>> Make the driver as part of matrix-keypad driver or bring real arguments
>> why it cannot be merged.
>
> I tryied to put real hardware scenario which used in
> Bosch Power tool measuring devices.
> Keypad schematic as below, it is reduced matrix keypad compared
> to standard matrix keypad
>
> Pin8 (gpio1 16)-----------------------
> Pin7 (gpio1 20)--------------------- |
> Pin6 (gpio1 22)------------------- | |
> Pin5 (gpio2 21)----------------- | | |
> Pin4 (ground )--------------- | | | |
> Pin3 (gpio1 31)------------- | | | | |
> Pin2 (gpio1 23)----------- | | | | | |
> Pin1 (gpio1 24)--------- | | | | | | |
> | | | | | | | |
> | | | | | | | |
> | | | | | | | |
> |------------|---------|----------------- | | | | | | |-----------|
> | Button1 | | Button2 | | | | | | Button3 |
> | _|_ | | _|_ | | | | | | _|_ |
> | |--o o--| |--o o-----------| | | | | |------o o--|
> | | | | | | | | |
> | | |----------------------------| | | | | | |
> | | Button4 | Button5 | | | | | Button6 |
> | | _|_ | _|_ | | | | | _|_ |
> | |--o o--| |---o o------------| | | | |---o o-----|
> | | | | | | |
> | | |------------------|---| | |-----------| |
> | | | | | |
> | |------------------------------| | |---------| | |
> | | | | | |
> | Button7 Button8 | | Button9 | | |
> | _|_ _|_ | | _|_ | | |
> |-----o o-----|--------o o----| |------o o----| | |
> | | | |
> | |---------------------------| |
> | |
> |-------------------------------------------------|
>
>
> ____________________________________
> | Button | Pin activation| Keymap |
> |----------------------------------|
> |Button1 | 1,6 | KEY_7 |
> |----------------------------------|
> |Button2 | 1,2 | KEY_8 |
> |----------------------------------|
> |Button3 | 7,8 | KEY_9 |
> |----------------------------------|
> |Button4 | 2,6 | KEY_4 |
> |----------------------------------|
> |Button5 | 3,4 | KEY_5 |
> |----------------------------------|
> |Button6 | 6,7 | KEY_6 |
> |----------------------------------|
> |Button7 | 1,8 | KEY_1 |
> |----------------------------------|
> |Button8 | 6,8 | KEY_2 |
> |----------------------------------|
> |Button9 | 4,5 | KEY_3 |
> |----------------------------------|
>
> for Button5 and Button9 we used standard gpio_keys.c driver.
>
> Button1,2,3,4,6,7,8 are not in standard row and column format,
> found difficulty to apply matrix keypad drive to these button.
>
> to solve this we came with vendor specific driver like
> mt_matrix_keypad.c by taking matrix_keypad as reference.
>
> after your review comment I felt it should named as
> bosch_keypad.c to show as vendor specific.
>
> in this driver all gpio lines act as row as well as column,
> a key can be placed at each intersection of a unique row
> number not equal to a unique column and they are diagonally
> symmetric.
> we can skip keymap for the valid intersection of gpio and
> invalid keymap for row equal to column.
>
> the matrix table as below for above schematic
>
> ------------------------------------------------------
> |Row\Col |GPIO 0 | GPIO 1 | GPIO 2 | GPIO 3 | GPIO 4 |
> ------------------------------------------------------
> | GPIO 0 | X | KEY_9 | KEY_2 | X | KEY_1 |
> ------------------------------------------------------
> | GPIO 1 | KEY_9 | X | KEY_6 | X | X |
> ------------------------------------------------------
> | GPIO 2 | KEY_2 | KEY_6 | X | KEY_4 | KEY_7 |
> ------------------------------------------------------
> | GPIO 3 | X | X | KEY_4 | X | KEY_8 |
> ------------------------------------------------------
> | GPIO 4 | KEY_1 | X | KEY_7 | KEY_8 | X |
> ------------------------------------------------------
> X - invalid key
> KEY_x - preferred key code
>
>
> in Device tree we avoided row and column
> and passed gpio info as line-gpios
>
> line-gpios = <
> &gpio1 24 1 /*gpio_56*/
> &gpio1 23 1 /*gpio_55*/
> &gpio1 22 1 /*gpio_54*/
> &gpio1 20 1 /*gpio_52*/
> &gpio1 16 1 /*gpio_48*/
> >;
> linux,keymap = <
> 0x00000000 /* row 0, col 0, KEY_RESERVED */
> 0x0001000a /* row 0, col 1, KEY_9 */
> 0x00020003 /* row 0, col 2, KEY_2 */
> 0x00030000 /* row 0, col 3, KEY_RESERVED */
> 0x00040002 /* row 0, col 4, KEY_1 */
> 0x0100000a /* row 1, col 0, KEY_9 */
> 0x01010000 /* row 1, col 1, KEY_RESERVED */
> 0x01020007 /* row 1, col 2, KEY_6 */
> 0x01030000 /* row 1, col 3, KEY_RESERVED */
> 0x01040000 /* row 1, col 4, KEY_RESERVED */
> 0x02000003 /* row 2, col 0, KEY_2 */
> 0x02010007 /* row 2, col 1, KEY_6 */
> 0x02020000 /* row 2, col 2, KEY_RESERVED */
> 0x02030005 /* row 2, col 3, KEY_4 */
> 0x02040008 /* row 2, col 4, KEY_7 */
> 0x03000000 /* row 3, col 0, KEY_RESERVED */
> 0x03010000 /* row 3, col 1, KEY_RESERVED */
> 0x03020005 /* row 3, col 2, KEY_4 */
> 0x03030000 /* row 3, col 3, KEY_RESERVED */
> 0x03040009 /* row 3, col 4, KEY_8 */
> 0x04000002 /* row 4, col 0, KEY_1 */
> 0x04010000 /* row 4, col 1, KEY_RESERVED */
> 0x04020008 /* row 4, col 2, KEY_7 */
> 0x04030009 /* row 4, col 3, KEY_8 */
> 0x04040000 /* row 4, col 4, KEY_RESERVED */
> >;
>
> this driver approch may be usefull for the embadded device
> which are using reduced matrix keypad

You wrote pretty long message explaining how the device works, but I
still do not see the answer to questions - why it cannot be part of
matrix keypad?

"It looks like this driver has smaller number of features than
matrix-keypad, so it should be integrated into the matrix-keypad.
matrix-keypad features are superset to this one."

"But anyway this should be just merged into matrix-keypad. It's a
simpler set of that binding."


Best regards,
Krzysztof

2022-05-14 00:13:27

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

Hi,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tmlind-omap/for-next]
[also build test WARNING on next-20220511]
[cannot apply to dtor-input/next robh/for-next balbi-usb/testing/next v5.18-rc6]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/intel-lab-lkp/linux/commits/Gireesh-Hiremath-in-bosch-com/ARM-dts-am335x-Guardian-switch-to-AM33XX_PADCONF-pinmux-macro/20220506-153118
base: https://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git for-next
config: riscv-randconfig-c006-20220508 (https://download.01.org/0day-ci/archive/20220512/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project af4cf1c6b8ed0d8102fc5e69acdc2fcbbcdaa9a7)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install riscv cross compiling tool for clang build
# apt-get install binutils-riscv64-linux-gnu
# https://github.com/intel-lab-lkp/linux/commit/eb3dca58cf317366877720c44e785ab0ce151ef8
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Gireesh-Hiremath-in-bosch-com/ARM-dts-am335x-Guardian-switch-to-AM33XX_PADCONF-pinmux-macro/20220506-153118
git checkout eb3dca58cf317366877720c44e785ab0ce151ef8
# save the config file
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=riscv clang-analyzer

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

>> drivers/input/keyboard/mt_matrix_keypad.c:200:7: warning: variable 'any_btn_served' set but not used [-Wunused-but-set-variable]
bool any_btn_served = false;
^
1 warning generated.


clang-analyzer warnings: (new ones prefixed by >>)
^~~~~~~
drivers/hwmon/w83627ehf.c:991:1: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
fan_functions(fan_step_output, data->REG_FAN_STEP_OUTPUT)
^
drivers/hwmon/w83627ehf.c:965:9: note: expanded from macro 'fan_functions'
return sprintf(buf, "%d\n", data->reg[nr]); \
^~~~~~~
drivers/hwmon/w83627ehf.c:991:1: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
fan_functions(fan_step_output, data->REG_FAN_STEP_OUTPUT)
^
drivers/hwmon/w83627ehf.c:965:9: note: expanded from macro 'fan_functions'
return sprintf(buf, "%d\n", data->reg[nr]); \
^~~~~~~
drivers/hwmon/w83627ehf.c:1027:1: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
fan_time_functions(fan_stop_time, W83627EHF_REG_FAN_STOP_TIME)
^
drivers/hwmon/w83627ehf.c:1001:9: note: expanded from macro 'fan_time_functions'
return sprintf(buf, "%d\n", \
^~~~~~~
drivers/hwmon/w83627ehf.c:1027:1: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
fan_time_functions(fan_stop_time, W83627EHF_REG_FAN_STOP_TIME)
^
drivers/hwmon/w83627ehf.c:1001:9: note: expanded from macro 'fan_time_functions'
return sprintf(buf, "%d\n", \
^~~~~~~
drivers/hwmon/w83627ehf.c:1082:9: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
^~~~~~~
drivers/hwmon/w83627ehf.c:1082:9: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
^~~~~~~
Suppressed 29 warnings (29 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
40 warnings generated.
Suppressed 40 warnings (40 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
53 warnings generated.
drivers/leds/leds-lp3952.c:104:2: warning: Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'strncpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
strncpy(dest, str, LP3952_LABEL_MAX_LEN);
^~~~~~~
drivers/leds/leds-lp3952.c:104:2: note: Call to function 'strncpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'strncpy_s' in case of C11
strncpy(dest, str, LP3952_LABEL_MAX_LEN);
^~~~~~~
Suppressed 52 warnings (52 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
59 warnings generated.
drivers/leds/leds-lp5521.c:230:9: warning: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
^~~~~~
drivers/leds/leds-lp5521.c:230:9: note: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11
ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
^~~~~~
drivers/leds/leds-lp5521.c:234:9: warning: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
ret = sscanf(c, "%2x", &cmd);
^~~~~~
drivers/leds/leds-lp5521.c:234:9: note: Call to function 'sscanf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sscanf_s' in case of C11
ret = sscanf(c, "%2x", &cmd);
^~~~~~
drivers/leds/leds-lp5521.c:306:2: warning: Value stored to 'ret' is never read [clang-analyzer-deadcode.DeadStores]
ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-lp5521.c:306:2: note: Value stored to 'ret' is never read
ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-lp5521.c:368:2: warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn]
return ret;
^ ~~~
drivers/leds/leds-lp5521.c:355:2: note: 'ret' declared without an initial value
int ret;
^~~~~~~
drivers/leds/leds-lp5521.c:359:14: note: Assuming 'i' is >= field 'num_colors'
for (i = 0; i < led->mc_cdev.num_colors; i++) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/leds-lp5521.c:359:2: note: Loop condition is false. Execution continues on line 367
for (i = 0; i < led->mc_cdev.num_colors; i++) {
^
drivers/leds/leds-lp5521.c:368:2: note: Undefined or garbage value returned to caller
return ret;
^ ~~~
drivers/leds/leds-lp5521.c:394:10: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
return sprintf(buf, "run\n");
^~~~~~~
drivers/leds/leds-lp5521.c:394:10: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
return sprintf(buf, "run\n");
^~~~~~~
drivers/leds/leds-lp5521.c:396:10: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
return sprintf(buf, "load\n");
^~~~~~~
drivers/leds/leds-lp5521.c:396:10: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
return sprintf(buf, "load\n");
^~~~~~~
drivers/leds/leds-lp5521.c:399:10: warning: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
return sprintf(buf, "disabled\n");
^~~~~~~
drivers/leds/leds-lp5521.c:399:10: note: Call to function 'sprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11
return sprintf(buf, "disabled\n");
^~~~~~~
Suppressed 52 warnings (52 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
43 warnings generated.
>> drivers/input/keyboard/mt_matrix_keypad.c:297:35: warning: Division by zero [clang-analyzer-core.DivideZero]
pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
^
drivers/input/keyboard/mt_matrix_keypad.c:346:6: note: Assuming field 'stopped' is equal to false
if (keypad->stopped == false) {
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:346:2: note: Taking true branch
if (keypad->stopped == false) {
^
drivers/input/keyboard/mt_matrix_keypad.c:347:3: note: Calling 'update_buttons'
update_buttons(pdata, input_dev);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:222:6: note: Assuming field 'scan_phase' is not equal to field 'phase_prepare'
if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:222:2: note: Taking false branch
if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
^
drivers/input/keyboard/mt_matrix_keypad.c:225:13: note: Assuming field 'scan_phase' is not equal to field 'phase_update_button'
} else if (pdata->scan_phase ==
^~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:225:9: note: Taking false branch
} else if (pdata->scan_phase ==
^
drivers/input/keyboard/mt_matrix_keypad.c:266:15: note: Assuming 'i' is >= field 'num_line_gpios'
for (i = 0; i < pdata->num_line_gpios; i++) {
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:266:3: note: Loop condition is false. Execution continues on line 277
for (i = 0; i < pdata->num_line_gpios; i++) {
^
drivers/input/keyboard/mt_matrix_keypad.c:277:7: note: 'number_of_buttons_pressed' is < 2
if (number_of_buttons_pressed < 2) {
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:277:3: note: Taking true branch
if (number_of_buttons_pressed < 2) {
^
drivers/input/keyboard/mt_matrix_keypad.c:278:4: note: Loop condition is false. Execution continues on line 293
for (i = 0; i < pdata->num_line_gpios; i++) {
^
drivers/input/keyboard/mt_matrix_keypad.c:297:35: note: Division by zero
pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/input/keyboard/mt_matrix_keypad.c:488:2: warning: Value stored to 'i' is never read [clang-analyzer-deadcode.DeadStores]
i = pdata->num_line_gpios;
^ ~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:488:2: note: Value stored to 'i' is never read
i = pdata->num_line_gpios;
^ ~~~~~~~~~~~~~~~~~~~~~
Suppressed 41 warnings (40 in non-user code, 1 with check filters).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
40 warnings generated.
Suppressed 40 warnings (40 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
52 warnings generated.
Suppressed 52 warnings (52 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
64 warnings generated.
drivers/media/dvb-frontends/cxd2841er.c:236:2: warning: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memcpy(&buf[1], data, len);
^
include/linux/fortify-string.h:369:26: note: expanded from macro 'memcpy'
#define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:362:2: note: expanded from macro '__fortify_memcpy_chk'
__underlying_##op(p, q, __fortify_size); \
^~~~~~~~~~~~~~~~~
note: expanded from here
include/linux/fortify-string.h:45:29: note: expanded from macro '__underlying_memcpy'
#define __underlying_memcpy __builtin_memcpy
^~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:236:2: note: Call to function 'memcpy' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memcpy_s' in case of C11
memcpy(&buf[1], data, len);
^
include/linux/fortify-string.h:369:26: note: expanded from macro 'memcpy'
#define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:362:2: note: expanded from macro '__fortify_memcpy_chk'
__underlying_##op(p, q, __fortify_size); \
^~~~~~~~~~~~~~~~~
note: expanded from here
include/linux/fortify-string.h:45:29: note: expanded from macro '__underlying_memcpy'
#define __underlying_memcpy __builtin_memcpy
^~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3600:25: warning: Value stored to 'priv' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
struct cxd2841er_priv *priv = fe->demodulator_priv;
^~~~ ~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3600:25: note: Value stored to 'priv' during its initialization is never read
struct cxd2841er_priv *priv = fe->demodulator_priv;
^~~~ ~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3714:2: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memset(data, 0, sizeof(data));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3714:2: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
memset(data, 0, sizeof(data));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3759:25: warning: Value stored to 'priv' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
struct cxd2841er_priv *priv = fe->demodulator_priv;
^~~~ ~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3759:25: note: Value stored to 'priv' during its initialization is never read
struct cxd2841er_priv *priv = fe->demodulator_priv;
^~~~ ~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3812:34: warning: Value stored to 'p' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^ ~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3812:34: note: Value stored to 'p' during its initialization is never read
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^ ~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3867:3: warning: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3867:3: note: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3873:3: warning: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3873:3: note: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3882:3: warning: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
drivers/media/dvb-frontends/cxd2841er.c:3882:3: note: Call to function 'snprintf' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'snprintf_s' in case of C11
snprintf(cxd2841er_t_c_ops.info.name, 128,
^~~~~~~~
--
^
drivers/media/i2c/ov5693.c:1404:6: note: Assuming 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1404:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1407:2: note: Loop condition is false. Exiting loop
mutex_init(&ov5693->lock);
^
include/linux/mutex.h:101:32: note: expanded from macro 'mutex_init'
#define mutex_init(mutex) \
^
drivers/media/i2c/ov5693.c:1412:2: note: Taking false branch
if (IS_ERR(ov5693->clk)) {
^
drivers/media/i2c/ov5693.c:1418:6: note: Assuming 'clk_rate' is equal to OV5693_XVCLK_FREQ
if (clk_rate != OV5693_XVCLK_FREQ)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/ov5693.c:1418:2: note: Taking false branch
if (clk_rate != OV5693_XVCLK_FREQ)
^
drivers/media/i2c/ov5693.c:1423:6: note: 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1423:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1427:6: note: Assuming 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1427:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1440:6: note: 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1440:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1444:6: note: Assuming 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1444:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1455:6: note: 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:1455:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:1458:8: note: Calling 'ov5693_detect'
ret = ov5693_detect(ov5693);
^~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/ov5693.c:871:2: note: 'id' declared without an initial value
u32 id;
^~~~~~
drivers/media/i2c/ov5693.c:873:8: note: Calling 'ov5693_read_reg'
ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID, &id);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/ov5693.c:399:8: note: '?' condition is false
reg = cpu_to_be16(addr & OV5693_REG_ADDR_MASK);
^
include/linux/byteorder/generic.h:96:21: note: expanded from macro 'cpu_to_be16'
#define cpu_to_be16 __cpu_to_be16
^
include/uapi/linux/byteorder/little_endian.h:42:43: note: expanded from macro '__cpu_to_be16'
#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
^
include/uapi/linux/swab.h:105:3: note: expanded from macro '__swab16'
(__builtin_constant_p((__u16)(x)) ? \
^
drivers/media/i2c/ov5693.c:404:6: note: Assuming 'ret' is < 0
if (ret < 0)
^~~~~~~
drivers/media/i2c/ov5693.c:404:2: note: Taking true branch
if (ret < 0)
^
drivers/media/i2c/ov5693.c:405:3: note: Returning without writing to '*value'
return dev_err_probe(&client->dev, ret,
^
drivers/media/i2c/ov5693.c:405:3: note: Returning value, which participates in a condition later
return dev_err_probe(&client->dev, ret,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/ov5693.c:873:8: note: Returning from 'ov5693_read_reg'
ret = ov5693_read_reg(ov5693, OV5693_REG_CHIP_ID, &id);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/media/i2c/ov5693.c:874:6: note: Assuming 'ret' is 0
if (ret)
^~~
drivers/media/i2c/ov5693.c:874:2: note: Taking false branch
if (ret)
^
drivers/media/i2c/ov5693.c:877:9: note: The left operand of '!=' is a garbage value
if (id != OV5693_CHIP_ID)
~~ ^
Suppressed 53 warnings (53 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
43 warnings generated.
>> drivers/input/keyboard/mt_matrix_keypad.c:297:35: warning: Division by zero [clang-analyzer-core.DivideZero]
pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
^
drivers/input/keyboard/mt_matrix_keypad.c:346:6: note: Assuming field 'stopped' is equal to false
if (keypad->stopped == false) {
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:346:2: note: Taking true branch
if (keypad->stopped == false) {
^
drivers/input/keyboard/mt_matrix_keypad.c:347:3: note: Calling 'update_buttons'
update_buttons(pdata, input_dev);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:222:6: note: Assuming field 'scan_phase' is not equal to field 'phase_prepare'
if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:222:2: note: Taking false branch
if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
^
drivers/input/keyboard/mt_matrix_keypad.c:225:13: note: Assuming field 'scan_phase' is not equal to field 'phase_update_button'
} else if (pdata->scan_phase ==
^~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:225:9: note: Taking false branch
} else if (pdata->scan_phase ==
^
drivers/input/keyboard/mt_matrix_keypad.c:266:15: note: Assuming 'i' is >= field 'num_line_gpios'
for (i = 0; i < pdata->num_line_gpios; i++) {
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:266:3: note: Loop condition is false. Execution continues on line 277
for (i = 0; i < pdata->num_line_gpios; i++) {
^
drivers/input/keyboard/mt_matrix_keypad.c:277:7: note: 'number_of_buttons_pressed' is < 2
if (number_of_buttons_pressed < 2) {
^~~~~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:277:3: note: Taking true branch
if (number_of_buttons_pressed < 2) {
^
drivers/input/keyboard/mt_matrix_keypad.c:278:4: note: Loop condition is false. Execution continues on line 293
for (i = 0; i < pdata->num_line_gpios; i++) {
^
drivers/input/keyboard/mt_matrix_keypad.c:297:35: note: Division by zero
pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/input/keyboard/mt_matrix_keypad.c:488:2: warning: Value stored to 'i' is never read [clang-analyzer-deadcode.DeadStores]
i = pdata->num_line_gpios;
^ ~~~~~~~~~~~~~~~~~~~~~
drivers/input/keyboard/mt_matrix_keypad.c:488:2: note: Value stored to 'i' is never read
i = pdata->num_line_gpios;
^ ~~~~~~~~~~~~~~~~~~~~~
Suppressed 41 warnings (40 in non-user code, 1 with check filters).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
40 warnings generated.
Suppressed 40 warnings (40 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
52 warnings generated.
Suppressed 52 warnings (52 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
37 warnings generated.
drivers/leds/uleds.c:150:4: warning: Value stored to 'retval' is never read [clang-analyzer-deadcode.DeadStores]
retval = copy_to_user(buffer, &udev->brightness,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/leds/uleds.c:150:4: note: Value stored to 'retval' is never read
retval = copy_to_user(buffer, &udev->brightness,
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppressed 36 warnings (36 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
53 warnings generated.
drivers/firmware/google/framebuffer-coreboot.c:54:2: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memset(&res, 0, sizeof(res));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
drivers/firmware/google/framebuffer-coreboot.c:54:2: note: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11
memset(&res, 0, sizeof(res));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \
^~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:47:29: note: expanded from macro '__underlying_memset'
#define __underlying_memset __builtin_memset
^~~~~~~~~~~~~~~~
Suppressed 52 warnings (52 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
86 warnings generated.
Suppressed 86 warnings (86 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
80 warnings generated.
Suppressed 80 warnings (80 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
95 warnings generated.
include/linux/etherdevice.h:128:2: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
u16 a = *(const u16 *)addr;
^
net/llc/llc_sap.c:425:2: note: Calling 'llc_pdu_decode_da'
llc_pdu_decode_da(skb, laddr.mac);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/net/llc_pdu.h:278:23: note: '?' condition is true
if (skb->protocol == htons(ETH_P_802_2))
^
include/linux/byteorder/generic.h:141:18: note: expanded from macro 'htons'
#define htons(x) ___htons(x)
^
include/linux/byteorder/generic.h:135:21: note: expanded from macro '___htons'
#define ___htons(x) __cpu_to_be16(x)
^
include/uapi/linux/byteorder/little_endian.h:42:43: note: expanded from macro '__cpu_to_be16'
#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
^
include/uapi/linux/swab.h:105:3: note: expanded from macro '__swab16'
(__builtin_constant_p((__u16)(x)) ? \
^
include/net/llc_pdu.h:278:6: note: Assuming the condition is false
if (skb->protocol == htons(ETH_P_802_2))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/net/llc_pdu.h:278:2: note: Taking false branch
if (skb->protocol == htons(ETH_P_802_2))
^
net/llc/llc_sap.c:425:2: note: Returning from 'llc_pdu_decode_da'
llc_pdu_decode_da(skb, laddr.mac);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/llc/llc_sap.c:428:6: note: Calling 'is_multicast_ether_addr'
if (is_multicast_ether_addr(laddr.mac)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/etherdevice.h:128:2: note: Assigned value is garbage or undefined
u16 a = *(const u16 *)addr;
^ ~~~~~~~~~~~~~~~~~~
net/llc/llc_sap.c:77:2: warning: Call to function 'memset' is insecure as it does not provide security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'memset_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling]
memset(addr, 0, sizeof(*addr));
^
include/linux/fortify-string.h:272:25: note: expanded from macro 'memset'
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/fortify-string.h:265:2: note: expanded from macro '__fortify_memset_chk'
__underlying_memset(p, c, __fortify_size); \

vim +/any_btn_served +200 drivers/input/keyboard/mt_matrix_keypad.c

195
196 void process_button_events(const struct mt_matrix_keypad_platform_data *pdata,
197 struct input_dev *input_dev)
198 {
199 int btn_index;
> 200 bool any_btn_served = false;
201
202 for (btn_index = 0; btn_index < pdata->num_of_buttons; btn_index++) {
203 const union typeEvent beEvent =
204 get_and_clear_btn_events(pdata, (int)btn_index);
205
206 if (beEvent.status.boGlobalChanged) {
207 const struct button_states bsState =
208 get_btn_id_state(pdata, (int)btn_index);
209
210 if (bsState.boEnabled) {
211 any_btn_served |=
212 on_button_event(pdata, (int)btn_index,
213 beEvent, input_dev);
214 }
215 }
216 }
217 }
218
219 void update_buttons(struct mt_matrix_keypad_platform_data *pdata,
220 struct input_dev *input_dev)
221 {
222 if (pdata->scan_phase == pdata->phase_state.phase_prepare) {
223 pdata->scan_phase = pdata->phase_state.phase_start;
224 activate_line_driving(pdata, (int)pdata->scan_phase, true);
225 } else if (pdata->scan_phase ==
226 pdata->phase_state.phase_update_button) {
227 bool btn_changes_occured = false;
228 int btn_index;
229
230 if (pdata->intialize_buttons) {
231 int i;
232
233 pdata->intialize_buttons = false;
234
235 for (i = 0; i < pdata->num_of_buttons; i++) {
236 const bool btn_curr_hw_state =
237 get_button_state(
238 &pdata->button_array[i])
239 .boCurrentStateOfHw;
240 button_init(&pdata->button_array[i],
241 btn_curr_hw_state,
242 pdata->button_array[i].key);
243 }
244 }
245
246 for (btn_index = 0; btn_index < pdata->num_of_buttons;
247 btn_index++) {
248 btn_changes_occured |= check_button_changes(
249 &pdata->button_array[btn_index]);
250 }
251
252 if (btn_changes_occured)
253 process_button_events(pdata, input_dev);
254
255 pdata->scan_phase = pdata->phase_state.phase_start;
256 } else {
257 uint8_t *btn_keylines;
258 uint8_t number_of_buttons_pressed = 0;
259 uint8_t btn_index;
260 uint8_t btn_key;
261 uint16_t index;
262 int i;
263
264 btn_keylines = kcalloc(pdata->num_line_gpios, sizeof(uint8_t),
265 GFP_KERNEL);
266 for (i = 0; i < pdata->num_line_gpios; i++) {
267 index = (pdata->scan_phase * pdata->num_line_gpios) + i;
268 btn_key = pdata->button_matrix[index];
269 btn_keylines[i] = false;
270
271 if ((btn_key != pdata->button_matrix[0]) &&
272 (get_gpio_line_value(pdata, (int)i) != false)) {
273 btn_keylines[i] = true;
274 number_of_buttons_pressed++;
275 }
276 }
277 if (number_of_buttons_pressed < 2) {
278 for (i = 0; i < pdata->num_line_gpios; i++) {
279 index = (pdata->scan_phase *
280 pdata->num_line_gpios) +
281 i;
282 btn_key = pdata->button_matrix[index];
283 if (btn_key != pdata->button_matrix[0]) {
284 btn_index =
285 get_btn_index(pdata, btn_key);
286 set_btn_state_by_hw(
287 &pdata->button_array[btn_index],
288 btn_keylines[i]);
289 }
290 }
291 }
292
293 kfree(btn_keylines);
294 activate_line_driving(pdata, (int)pdata->scan_phase, false);
295 pdata->scan_phase++;
296 activate_line_driving(
> 297 pdata, (int)(pdata->scan_phase % pdata->num_line_gpios),
298 true);
299 }
300 }
301

--
0-DAY CI Kernel Test Service
https://01.org/lkp

2022-06-13 08:41:55

by Gireesh.Hiremath

[permalink] [raw]
Subject: Re: [v2,2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

From: Gireesh Hiremath <[email protected]>

Hi Krzysztof,

>You wrote pretty long message explaining how the device works, but I
>still do not see the answer to questions - why it cannot be part of
>matrix keypad?

Following are the difference between matrix keypad and Bosch keypad
make us to add another keypad driver.

matrix keypad:
- By hardware schematic, a column GPIO line will intersect only
with row GPIO lines, not with the other column GPIO lines
- so, row and column GPIO property are fixed, because of this
- key scanning work based on interrupt mode
- and key press is determined based on setting column as output,
row GPIO as input and set interrupt to monitor the changes in state,
serve the key pressed in ISR

Bosch keypad:
- By hardware schematic column GPIO line can intersect with row GPIO line
as well as other column GPIO lines
- so, all GPIO act as row as well as column, because of this
- key scanning based on polling mode
- a key pressed is determined by setting one of GPIO line as output and
other as input and poll for change in the state of input GPIO lines.
Setting one of a GPIO line as output and remaining GPIO lines as input is on
round robin bases.
>
>"It looks like this driver has smaller number of features than
>matrix-keypad, so it should be integrated into the matrix-keypad.
>matrix-keypad features are superset to this one."
>
>"But anyway this should be just merged into matrix-keypad. It's a
>simpler set of that binding."

This keypad driver specific to Bosch measuring tool or similar devices.
Please let me know to send latest patch which resolves build warning
and gpiod API support.

Best regards,
Gireesh Hiremath

2022-06-15 08:56:36

by Marco Felsch

[permalink] [raw]
Subject: Re: [v2,2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

Hi,

sry. for jumping in again.

On 22-06-13, [email protected] wrote:
> From: Gireesh Hiremath <[email protected]>
>
> Hi Krzysztof,
>
> >You wrote pretty long message explaining how the device works, but I
> >still do not see the answer to questions - why it cannot be part of
> >matrix keypad?
>
> Following are the difference between matrix keypad and Bosch keypad
> make us to add another keypad driver.
>
> matrix keypad:
> - By hardware schematic, a column GPIO line will intersect only
> with row GPIO lines, not with the other column GPIO lines
> - so, row and column GPIO property are fixed, because of this
> - key scanning work based on interrupt mode
> - and key press is determined based on setting column as output,
> row GPIO as input and set interrupt to monitor the changes in state,
> serve the key pressed in ISR
>
> Bosch keypad:
> - By hardware schematic column GPIO line can intersect with row GPIO line
> as well as other column GPIO lines
> - so, all GPIO act as row as well as column, because of this
> - key scanning based on polling mode
> - a key pressed is determined by setting one of GPIO line as output and
> other as input and poll for change in the state of input GPIO lines.
> Setting one of a GPIO line as output and remaining GPIO lines as input is on
> round robin bases.

Thanks again for listing this here but please get our point, that this
seems like just another 'mode' for the matrix keypad driver which can be
selected by the system integrator.

> >"It looks like this driver has smaller number of features than
> >matrix-keypad, so it should be integrated into the matrix-keypad.
> >matrix-keypad features are superset to this one."
> >
> >"But anyway this should be just merged into matrix-keypad. It's a
> >simpler set of that binding."
>
> This keypad driver specific to Bosch measuring tool or similar devices.

Once it lands in mainline, it can be used by everyone.

> Please let me know to send latest patch which resolves build warning
> and gpiod API support.

I would really appreciate if you could integrate your work into matrix
keypad driver.

Regards,
Marco

2022-06-15 21:12:59

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [v2,2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

On 13/06/2022 01:06, [email protected] wrote:
> From: Gireesh Hiremath <[email protected]>
>
> Hi Krzysztof,
>
>> You wrote pretty long message explaining how the device works, but I
>> still do not see the answer to questions - why it cannot be part of
>> matrix keypad?
>
> Following are the difference between matrix keypad and Bosch keypad
> make us to add another keypad driver.
>
> matrix keypad:
> - By hardware schematic, a column GPIO line will intersect only
> with row GPIO lines, not with the other column GPIO lines
> - so, row and column GPIO property are fixed, because of this
> - key scanning work based on interrupt mode
> - and key press is determined based on setting column as output,
> row GPIO as input and set interrupt to monitor the changes in state,
> serve the key pressed in ISR
>
> Bosch keypad:
> - By hardware schematic column GPIO line can intersect with row GPIO line
> as well as other column GPIO lines
> - so, all GPIO act as row as well as column, because of this
> - key scanning based on polling mode
> - a key pressed is determined by setting one of GPIO line as output and
> other as input and poll for change in the state of input GPIO lines.
> Setting one of a GPIO line as output and remaining GPIO lines as input is on
> round robin bases.

Which is still not the answer "why it cannot be part of matrix keypad?".
To me looks similar enough, although maybe not exactly superset of the
other.

>>
>> "It looks like this driver has smaller number of features than
>> matrix-keypad, so it should be integrated into the matrix-keypad.
>> matrix-keypad features are superset to this one."
>>
>> "But anyway this should be just merged into matrix-keypad. It's a
>> simpler set of that binding."
>
> This keypad driver specific to Bosch measuring tool or similar devices.
> Please let me know to send latest patch which resolves build warning
> and gpiod API support.

That's a poor reason not to merge into existing driver... I am sorry,
but our entire Linux kernel concept is to integrate, not duplicate. If
each of vendors wanted their own feature, we would have unmanageable
monstrosity with millions of drivers doing almost the same...


Best regards,
Krzysztof

2022-08-19 07:13:46

by Gireesh.Hiremath

[permalink] [raw]
Subject: Re: [v2,2/4] Input: mt-matrix-keypad: Add Bosch mt matrix keypad driver

From: Gireesh Hiremath <[email protected]>

Hi Krzysztof,

>>> You wrote pretty long message explaining how the device works, but I
>>> still do not see the answer to questions - why it cannot be part of
>>> matrix keypad?
>>
>> Following are the difference between matrix keypad and Bosch keypad
>> make us to add another keypad driver.
>>
>> matrix keypad:
>> - By hardware schematic, a column GPIO line will intersect only
>> with row GPIO lines, not with the other column GPIO lines
>> - so, row and column GPIO property are fixed, because of this
>> - key scanning work based on interrupt mode
>> - and key press is determined based on setting column as output,
>> row GPIO as input and set interrupt to monitor the changes in state,
>> serve the key pressed in ISR
>>
>> Bosch keypad:
>> - By hardware schematic column GPIO line can intersect with row GPIO line
>> as well as other column GPIO lines
>> - so, all GPIO act as row as well as column, because of this
>> - key scanning based on polling mode
>> - a key pressed is determined by setting one of GPIO line as output and
>> other as input and poll for change in the state of input GPIO lines.
>> Setting one of a GPIO line as output and remaining GPIO lines as input is on
>> round robin bases.
>
>Which is still not the answer "why it cannot be part of matrix keypad?".
>To me looks similar enough, although maybe not exactly superset of the
>other.

I have merged the Bosch keypad in to the matrix keypad
and sending version v3 patches to support that.

v3-0001-driver-input-matric-keypad-switch-to-gpiod.patch
v3-0002-driver-input-matric-keypad-add-reduced-matrix-sup.patch
v3-0003-dt-bindings-input-gpio-matrix-keypad-add-reduced-.patch

>
>>>
>>> "It looks like this driver has smaller number of features than
>>> matrix-keypad, so it should be integrated into the matrix-keypad.
>>> matrix-keypad features are superset to this one."
>>>
>>> "But anyway this should be just merged into matrix-keypad. It's a
>>> simpler set of that binding."
>>
>> This keypad driver specific to Bosch measuring tool or similar devices.
>> Please let me know to send latest patch which resolves build warning
>> and gpiod API support.
>
>That's a poor reason not to merge into existing driver... I am sorry,
>but our entire Linux kernel concept is to integrate, not duplicate. If
>each of vendors wanted their own feature, we would have unmanageable
>monstrosity with millions of drivers doing almost the same...
>
>
>Best regards,
>Krzysztof
>

Best regards,
Gireesh Hiremath