Source
34
34
};
35
35
36
36
static int twl6040_pdmclk_is_prepared(struct clk_hw *hw)
37
37
{
38
38
struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
39
39
pdmclk_hw);
40
40
41
41
return pdmclk->enabled;
42
42
}
43
43
44
+
static int twl6040_pdmclk_reset_one_clock(struct twl6040_pdmclk *pdmclk,
45
+
unsigned int reg)
46
+
{
47
+
const u8 reset_mask = TWL6040_HPLLRST; /* Same for HPPLL and LPPLL */
48
+
int ret;
49
+
50
+
ret = twl6040_set_bits(pdmclk->twl6040, reg, reset_mask);
51
+
if (ret < 0)
52
+
return ret;
53
+
54
+
ret = twl6040_clear_bits(pdmclk->twl6040, reg, reset_mask);
55
+
if (ret < 0)
56
+
return ret;
57
+
58
+
return 0;
59
+
}
60
+
61
+
/*
62
+
* TWL6040A2 Phoenix Audio IC erratum #6: "PDM Clock Generation Issue At
63
+
* Cold Temperature". This affects cold boot and deeper idle states it
64
+
* seems. The workaround consists of resetting HPPLL and LPPLL.
65
+
*/
66
+
static int twl6040_pdmclk_quirk_reset_clocks(struct twl6040_pdmclk *pdmclk)
67
+
{
68
+
int ret;
69
+
70
+
ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_HPPLLCTL);
71
+
if (ret)
72
+
return ret;
73
+
74
+
ret = twl6040_pdmclk_reset_one_clock(pdmclk, TWL6040_REG_LPPLLCTL);
75
+
if (ret)
76
+
return ret;
77
+
78
+
return 0;
79
+
}
80
+
44
81
static int twl6040_pdmclk_prepare(struct clk_hw *hw)
45
82
{
46
83
struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
47
84
pdmclk_hw);
48
85
int ret;
49
86
50
87
ret = twl6040_power(pdmclk->twl6040, 1);
51
-
if (!ret)
52
-
pdmclk->enabled = 1;
88
+
if (ret)
89
+
return ret;
90
+
91
+
ret = twl6040_pdmclk_quirk_reset_clocks(pdmclk);
92
+
if (ret)
93
+
goto out_err;
94
+
95
+
pdmclk->enabled = 1;
96
+
97
+
return 0;
98
+
99
+
out_err:
100
+
dev_err(pdmclk->dev, "%s: error %i\n", __func__, ret);
101
+
twl6040_power(pdmclk->twl6040, 0);
53
102
54
103
return ret;
55
104
}
56
105
57
106
static void twl6040_pdmclk_unprepare(struct clk_hw *hw)
58
107
{
59
108
struct twl6040_pdmclk *pdmclk = container_of(hw, struct twl6040_pdmclk,
60
109
pdmclk_hw);
61
110
int ret;
62
111