4444#define S5PV210_KEYIFSTSCLR_R_INT_OFFSET 16
4545
4646/* SAMSUNG_KEYIFCOL */
47- #define SAMSUNG_KEYIFCOL_MASK (0xff << 0)
48- #define S5PV210_KEYIFCOLEN_MASK (0xff << 8)
47+ #define SAMSUNG_KEYIFCOL_MASK 0xff
4948
5049/* SAMSUNG_KEYIFROW */
5150#define SAMSUNG_KEYIFROW_MASK (0xff << 0)
5453/* SAMSUNG_KEYIFFC */
5554#define SAMSUNG_KEYIFFC_MASK (0x3ff << 0)
5655
57- enum samsung_keypad_type {
58- KEYPAD_TYPE_SAMSUNG ,
59- KEYPAD_TYPE_S5PV210 ,
56+ struct samsung_chip_info {
57+ unsigned int column_shift ;
6058};
6159
6260struct samsung_keypad {
61+ const struct samsung_chip_info * chip ;
6362 struct input_dev * input_dev ;
6463 struct platform_device * pdev ;
6564 struct clk * clk ;
@@ -68,7 +67,6 @@ struct samsung_keypad {
6867 bool stopped ;
6968 bool wake_enabled ;
7069 int irq ;
71- enum samsung_keypad_type type ;
7270 unsigned int row_shift ;
7371 unsigned int rows ;
7472 unsigned int cols ;
@@ -83,13 +81,8 @@ static void samsung_keypad_scan(struct samsung_keypad *keypad,
8381 unsigned int val ;
8482
8583 for (col = 0 ; col < keypad -> cols ; col ++ ) {
86- if (keypad -> type == KEYPAD_TYPE_S5PV210 ) {
87- val = S5PV210_KEYIFCOLEN_MASK ;
88- val &= ~(1 << col ) << 8 ;
89- } else {
90- val = SAMSUNG_KEYIFCOL_MASK ;
91- val &= ~(1 << col );
92- }
84+ val = SAMSUNG_KEYIFCOL_MASK & ~(1 << col );
85+ val <<= keypad -> chip -> column_shift ;
9386
9487 writel (val , keypad -> base + SAMSUNG_KEYIFCOL );
9588 mdelay (1 );
@@ -314,6 +307,7 @@ static int samsung_keypad_probe(struct platform_device *pdev)
314307{
315308 const struct samsung_keypad_platdata * pdata ;
316309 const struct matrix_keymap_data * keymap_data ;
310+ const struct platform_device_id * id ;
317311 struct samsung_keypad * keypad ;
318312 struct resource * res ;
319313 struct input_dev * input_dev ;
@@ -378,11 +372,17 @@ static int samsung_keypad_probe(struct platform_device *pdev)
378372 keypad -> stopped = true;
379373 init_waitqueue_head (& keypad -> wait );
380374
381- if (pdev -> dev .of_node )
382- keypad -> type = of_device_is_compatible (pdev -> dev .of_node ,
383- "samsung,s5pv210-keypad" );
384- else
385- keypad -> type = platform_get_device_id (pdev )-> driver_data ;
375+ keypad -> chip = device_get_match_data (& pdev -> dev );
376+ if (!keypad -> chip ) {
377+ id = platform_get_device_id (pdev );
378+ if (id )
379+ keypad -> chip = (const void * )id -> driver_data ;
380+ }
381+
382+ if (!keypad -> chip ) {
383+ dev_err (& pdev -> dev , "Unable to determine chip type" );
384+ return - EINVAL ;
385+ }
386386
387387 input_dev -> name = pdev -> name ;
388388 input_dev -> id .bustype = BUS_HOST ;
@@ -542,24 +542,37 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = {
542542 samsung_keypad_runtime_resume , NULL )
543543};
544544
545+ static const struct samsung_chip_info samsung_s3c6410_chip_info = {
546+ .column_shift = 0 ,
547+ };
548+
549+ static const struct samsung_chip_info samsung_s5pv210_chip_info = {
550+ .column_shift = 8 ,
551+ };
552+
545553#ifdef CONFIG_OF
546554static const struct of_device_id samsung_keypad_dt_match [] = {
547- { .compatible = "samsung,s3c6410-keypad" },
548- { .compatible = "samsung,s5pv210-keypad" },
549- {},
555+ {
556+ .compatible = "samsung,s3c6410-keypad" ,
557+ .data = & samsung_s3c6410_chip_info ,
558+ }, {
559+ .compatible = "samsung,s5pv210-keypad" ,
560+ .data = & samsung_s5pv210_chip_info ,
561+ },
562+ { }
550563};
551564MODULE_DEVICE_TABLE (of , samsung_keypad_dt_match );
552565#endif
553566
554567static const struct platform_device_id samsung_keypad_driver_ids [] = {
555568 {
556569 .name = "samsung-keypad" ,
557- .driver_data = KEYPAD_TYPE_SAMSUNG ,
570+ .driver_data = ( kernel_ulong_t ) & samsung_s3c6410_chip_info ,
558571 }, {
559572 .name = "s5pv210-keypad" ,
560- .driver_data = KEYPAD_TYPE_S5PV210 ,
573+ .driver_data = ( kernel_ulong_t ) & samsung_s5pv210_chip_info ,
561574 },
562- { },
575+ { }
563576};
564577MODULE_DEVICE_TABLE (platform , samsung_keypad_driver_ids );
565578
0 commit comments