33 * Copyright (C) 2018 Spreadtrum Communications Inc.
44 */
55
6+ #include <linux/device.h>
7+ #include <linux/input.h>
8+ #include <linux/mod_devicetable.h>
69#include <linux/module.h>
7- #include <linux/of_address.h>
810#include <linux/platform_device.h>
11+ #include <linux/property.h>
912#include <linux/regmap.h>
10- #include <linux/input.h>
1113#include <linux/workqueue.h>
1214
13- #define CUR_DRV_CAL_SEL GENMASK(13, 12)
14- #define SLP_LDOVIBR_PD_EN BIT(9)
15- #define LDO_VIBR_PD BIT(8)
15+ #define CUR_DRV_CAL_SEL GENMASK(13, 12)
16+ #define SLP_LDOVIBR_PD_EN BIT(9)
17+ #define LDO_VIBR_PD BIT(8)
18+ #define SC2730_CUR_DRV_CAL_SEL 0
19+ #define SC2730_SLP_LDOVIBR_PD_EN BIT(14)
20+ #define SC2730_LDO_VIBR_PD BIT(13)
21+
22+ struct sc27xx_vibra_data {
23+ u32 cur_drv_cal_sel ;
24+ u32 slp_pd_en ;
25+ u32 ldo_pd ;
26+ };
1627
1728struct vibra_info {
1829 struct input_dev * input_dev ;
1930 struct work_struct play_work ;
2031 struct regmap * regmap ;
32+ const struct sc27xx_vibra_data * data ;
2133 u32 base ;
2234 u32 strength ;
2335 bool enabled ;
2436};
2537
38+ static const struct sc27xx_vibra_data sc2731_data = {
39+ .cur_drv_cal_sel = CUR_DRV_CAL_SEL ,
40+ .slp_pd_en = SLP_LDOVIBR_PD_EN ,
41+ .ldo_pd = LDO_VIBR_PD ,
42+ };
43+
44+ static const struct sc27xx_vibra_data sc2730_data = {
45+ .cur_drv_cal_sel = SC2730_CUR_DRV_CAL_SEL ,
46+ .slp_pd_en = SC2730_SLP_LDOVIBR_PD_EN ,
47+ .ldo_pd = SC2730_LDO_VIBR_PD ,
48+ };
49+
50+ static const struct sc27xx_vibra_data sc2721_data = {
51+ .cur_drv_cal_sel = CUR_DRV_CAL_SEL ,
52+ .slp_pd_en = SLP_LDOVIBR_PD_EN ,
53+ .ldo_pd = LDO_VIBR_PD ,
54+ };
55+
2656static void sc27xx_vibra_set (struct vibra_info * info , bool on )
2757{
58+ const struct sc27xx_vibra_data * data = info -> data ;
2859 if (on ) {
29- regmap_update_bits (info -> regmap , info -> base , LDO_VIBR_PD , 0 );
60+ regmap_update_bits (info -> regmap , info -> base , data -> ldo_pd , 0 );
3061 regmap_update_bits (info -> regmap , info -> base ,
31- SLP_LDOVIBR_PD_EN , 0 );
62+ data -> slp_pd_en , 0 );
3263 info -> enabled = true;
3364 } else {
34- regmap_update_bits (info -> regmap , info -> base , LDO_VIBR_PD ,
35- LDO_VIBR_PD );
65+ regmap_update_bits (info -> regmap , info -> base , data -> ldo_pd ,
66+ data -> ldo_pd );
3667 regmap_update_bits (info -> regmap , info -> base ,
37- SLP_LDOVIBR_PD_EN , SLP_LDOVIBR_PD_EN );
68+ data -> slp_pd_en , data -> slp_pd_en );
3869 info -> enabled = false;
3970 }
4071}
4172
4273static int sc27xx_vibra_hw_init (struct vibra_info * info )
4374{
44- return regmap_update_bits (info -> regmap , info -> base , CUR_DRV_CAL_SEL , 0 );
75+ const struct sc27xx_vibra_data * data = info -> data ;
76+
77+ if (!data -> cur_drv_cal_sel )
78+ return 0 ;
79+
80+ return regmap_update_bits (info -> regmap , info -> base ,
81+ data -> cur_drv_cal_sel , 0 );
4582}
4683
4784static void sc27xx_vibra_play_work (struct work_struct * work )
@@ -78,8 +115,15 @@ static void sc27xx_vibra_close(struct input_dev *input)
78115static int sc27xx_vibra_probe (struct platform_device * pdev )
79116{
80117 struct vibra_info * info ;
118+ const struct sc27xx_vibra_data * data ;
81119 int error ;
82120
121+ data = device_get_match_data (& pdev -> dev );
122+ if (!data ) {
123+ dev_err (& pdev -> dev , "no matching driver data found\n" );
124+ return - EINVAL ;
125+ }
126+
83127 info = devm_kzalloc (& pdev -> dev , sizeof (* info ), GFP_KERNEL );
84128 if (!info )
85129 return - ENOMEM ;
@@ -105,6 +149,7 @@ static int sc27xx_vibra_probe(struct platform_device *pdev)
105149 info -> input_dev -> name = "sc27xx:vibrator" ;
106150 info -> input_dev -> id .version = 0 ;
107151 info -> input_dev -> close = sc27xx_vibra_close ;
152+ info -> data = data ;
108153
109154 input_set_drvdata (info -> input_dev , info );
110155 input_set_capability (info -> input_dev , EV_FF , FF_RUMBLE );
@@ -134,7 +179,9 @@ static int sc27xx_vibra_probe(struct platform_device *pdev)
134179}
135180
136181static const struct of_device_id sc27xx_vibra_of_match [] = {
137- { .compatible = "sprd,sc2731-vibrator" , },
182+ { .compatible = "sprd,sc2721-vibrator" , .data = & sc2721_data },
183+ { .compatible = "sprd,sc2730-vibrator" , .data = & sc2730_data },
184+ { .compatible = "sprd,sc2731-vibrator" , .data = & sc2731_data },
138185 {}
139186};
140187MODULE_DEVICE_TABLE (of , sc27xx_vibra_of_match );
0 commit comments