11
11
#include <linux/platform_device.h>
12
12
#include <linux/slab.h>
13
13
14
- #define VREG_STATE 2
14
+ #define VREG_STATE 2
15
+ #define VREG_GRP 0
15
16
#define TWL6030_CFG_STATE_OFF 0x00
16
17
#define TWL6030_CFG_STATE_ON 0x01
17
18
#define TWL6030_CFG_STATE_MASK 0x03
19
+ #define TWL6030_CFG_STATE_GRP_SHIFT 5
20
+ #define TWL6030_CFG_STATE_APP_SHIFT 2
21
+ #define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
22
+ #define TWL6030_CFG_STATE_APP (v ) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
23
+ TWL6030_CFG_STATE_APP_SHIFT)
24
+ #define P1_GRP BIT(0) /* processor power group */
25
+ #define P2_GRP BIT(1)
26
+ #define P3_GRP BIT(2)
27
+ #define ALL_GRP (P1_GRP | P2_GRP | P3_GRP)
28
+
29
+ enum twl_type {
30
+ TWL_TYPE_6030 ,
31
+ TWL_TYPE_6032 ,
32
+ };
18
33
19
34
struct twl_clock_info {
20
35
struct device * dev ;
36
+ enum twl_type type ;
21
37
u8 base ;
22
38
struct clk_hw hw ;
23
39
};
@@ -56,23 +72,36 @@ static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
56
72
static int twl6032_clks_prepare (struct clk_hw * hw )
57
73
{
58
74
struct twl_clock_info * cinfo = to_twl_clks_info (hw );
59
- int ret ;
60
75
61
- ret = twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
62
- TWL6030_CFG_STATE_ON );
63
- if (ret < 0 )
64
- dev_err (cinfo -> dev , "clk prepare failed\n" );
76
+ if (cinfo -> type == TWL_TYPE_6030 ) {
77
+ int grp ;
78
+
79
+ grp = twlclk_read (cinfo , TWL_MODULE_PM_RECEIVER , VREG_GRP );
80
+ if (grp < 0 )
81
+ return grp ;
65
82
66
- return ret ;
83
+ return twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
84
+ grp << TWL6030_CFG_STATE_GRP_SHIFT |
85
+ TWL6030_CFG_STATE_ON );
86
+ }
87
+
88
+ return twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
89
+ TWL6030_CFG_STATE_ON );
67
90
}
68
91
69
92
static void twl6032_clks_unprepare (struct clk_hw * hw )
70
93
{
71
94
struct twl_clock_info * cinfo = to_twl_clks_info (hw );
72
95
int ret ;
73
96
74
- ret = twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
75
- TWL6030_CFG_STATE_OFF );
97
+ if (cinfo -> type == TWL_TYPE_6030 )
98
+ ret = twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
99
+ ALL_GRP << TWL6030_CFG_STATE_GRP_SHIFT |
100
+ TWL6030_CFG_STATE_OFF );
101
+ else
102
+ ret = twlclk_write (cinfo , TWL_MODULE_PM_RECEIVER , VREG_STATE ,
103
+ TWL6030_CFG_STATE_OFF );
104
+
76
105
if (ret < 0 )
77
106
dev_err (cinfo -> dev , "clk unprepare failed\n" );
78
107
}
@@ -138,6 +167,7 @@ static int twl_clks_probe(struct platform_device *pdev)
138
167
for (i = 0 ; i < count ; i ++ ) {
139
168
cinfo [i ].base = hw_data [i ].base ;
140
169
cinfo [i ].dev = & pdev -> dev ;
170
+ cinfo [i ].type = platform_get_device_id (pdev )-> driver_data ;
141
171
cinfo [i ].hw .init = & hw_data [i ].init ;
142
172
ret = devm_clk_hw_register (& pdev -> dev , & cinfo [i ].hw );
143
173
if (ret ) {
@@ -159,7 +189,11 @@ static int twl_clks_probe(struct platform_device *pdev)
159
189
160
190
static const struct platform_device_id twl_clks_id [] = {
161
191
{
192
+ .name = "twl6030-clk" ,
193
+ .driver_data = TWL_TYPE_6030 ,
194
+ }, {
162
195
.name = "twl6032-clk" ,
196
+ .driver_data = TWL_TYPE_6032 ,
163
197
}, {
164
198
/* sentinel */
165
199
}
0 commit comments