[oe] GCC5.2 causing bug in si5351 kernel driver
Radek Dostál
radek.dostal at streamunlimited.com
Wed Oct 28 18:28:08 UTC 2015
Dear All,
I have experienced bug in si5351 kernel driver, when compiled with gcc5.2.
Gcc5.2 obtained from: poky-jethro-14.0.0
hash: 8a0d8eee432924433c3e70198aaeab3161476c5f
Platform build: tune-cortexa8.inc with default tunes
Symptoms: si5351 is not configured properly and it outputs only 16.5MHz
instead of requested 22MHz.
Possible workarounds:
1) use older version of gcc such as ubuntu 14.04 default
4.7.3-12ubuntu1cross1.85
2) add kprintf to the code si5351 driver. See attached workaround.diff
Not possible workarounds:
1) Adding udelay(1000) instead of kprintf
2) kprintf printing similarly long text not using "*parent_rate"
Conclusion from above:
It is not a timing issue, but some optimization bug in gcc5.2
Attached is disassembly of clk-si5351.o with and without applied workaround
Maybe somebody can see something obvious in the disassembled code.
Thanks,
Radek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: workaround.diff
Type: text/x-patch
Size: 493 bytes
Desc: not available
URL: <http://lists.openembedded.org/pipermail/openembedded-devel/attachments/20151028/c8c34afc/attachment-0002.bin>
-------------- next part --------------
./drivers/clk/clk-si5351.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <si5351_regmap_is_volatile>:
}
}
static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
0: e3510001 cmp r1, #1
4: 9a000003 bls 18 <si5351_regmap_is_volatile+0x18>
8: e35100b1 cmp r1, #177 ; 0xb1
c: 0a000001 beq 18 <si5351_regmap_is_volatile+0x18>
case SI5351_DEVICE_STATUS:
case SI5351_INTERRUPT_STATUS:
case SI5351_PLL_RESET:
return true;
}
return false;
10: e3a00000 mov r0, #0
14: e12fff1e bx lr
{
switch (reg) {
case SI5351_DEVICE_STATUS:
case SI5351_INTERRUPT_STATUS:
case SI5351_PLL_RESET:
return true;
18: e3a00001 mov r0, #1
}
return false;
}
1c: e12fff1e bx lr
00000020 <si5351_vxco_unprepare>:
return 0;
}
static void si5351_vxco_unprepare(struct clk_hw *hw)
{
20: e12fff1e bx lr
00000024 <si5351_vxco_recalc_rate>:
static unsigned long si5351_vxco_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return 0;
}
24: e3a00000 mov r0, #0
28: e12fff1e bx lr
0000002c <si5351_vxco_set_rate>:
static int si5351_vxco_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent)
{
return 0;
}
2c: e3a00000 mov r0, #0
30: e12fff1e bx lr
00000034 <si5351_pll_get_parent>:
(parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
return 0;
}
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
34: e92d4030 push {r4, r5, lr}
38: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
3c: e5d03020 ldrb r3, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
40: e28d2004 add r2, sp, #4
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
44: e590400c ldr r4, [r0, #12]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
48: e3a0100f mov r1, #15
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
4c: e3530000 cmp r3, #0
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
50: e5940008 ldr r0, [r4, #8]
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
54: 13a05008 movne r5, #8
58: 03a05004 moveq r5, #4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
5c: ebfffffe bl 0 <regmap_read>
if (ret) {
60: e3500000 cmp r0, #0
64: 1a000005 bne 80 <si5351_pll_get_parent+0x4c>
68: e59d3004 ldr r3, [sp, #4]
6c: e1150003 tst r5, r3
70: 13a00001 movne r0, #1
74: 03a00000 moveq r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
return (val & mask) ? 1 : 0;
}
78: e28dd00c add sp, sp, #12
7c: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
80: e5940004 ldr r0, [r4, #4]
84: e3001000 movw r1, #0
88: e3401000 movt r1, #0
8c: e3a0200f mov r2, #15
90: e2800020 add r0, r0, #32
94: ebfffffe bl 0 <dev_err>
98: e3a00000 mov r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
return (val & mask) ? 1 : 0;
}
9c: e28dd00c add sp, sp, #12
a0: e8bd8030 pop {r4, r5, pc}
000000a4 <si5351_msynth_get_parent>:
SI5351_CLK_PLL_SELECT);
return 0;
}
static unsigned char si5351_msynth_get_parent(struct clk_hw *hw)
{
a4: e92d4030 push {r4, r5, lr}
a8: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
ac: e5d04020 ldrb r4, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
b0: e28d2004 add r2, sp, #4
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
b4: e590500c ldr r5, [r0, #12]
b8: e2844010 add r4, r4, #16
bc: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c0: e5950008 ldr r0, [r5, #8]
c4: e1a01004 mov r1, r4
c8: ebfffffe bl 0 <regmap_read>
if (ret) {
cc: e3500000 cmp r0, #0
d0: 05dd0004 ldrbeq r0, [sp, #4]
d4: 07e002d0 ubfxeq r0, r0, #5, #1
d8: 1a000001 bne e4 <si5351_msynth_get_parent+0x40>
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
dc: e28dd00c add sp, sp, #12
e0: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
e4: e5950004 ldr r0, [r5, #4]
e8: e3001000 movw r1, #0
ec: e1a02004 mov r2, r4
f0: e3401000 movt r1, #0
f4: e2800020 add r0, r0, #32
f8: ebfffffe bl 0 <dev_err>
fc: e3a00000 mov r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
100: e28dd00c add sp, sp, #12
104: e8bd8030 pop {r4, r5, pc}
00000108 <si5351_clkout_get_parent>:
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), (1 << hwdata->num));
}
static u8 si5351_clkout_get_parent(struct clk_hw *hw)
{
108: e92d4030 push {r4, r5, lr}
10c: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
int index = 0;
unsigned char val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
110: e5d04020 ldrb r4, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
114: e28d2004 add r2, sp, #4
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
int index = 0;
unsigned char val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
118: e590500c ldr r5, [r0, #12]
11c: e2844010 add r4, r4, #16
120: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
124: e5950008 ldr r0, [r5, #8]
128: e1a01004 mov r1, r4
12c: ebfffffe bl 0 <regmap_read>
if (ret) {
130: e3500000 cmp r0, #0
134: 1a000007 bne 158 <si5351_clkout_get_parent+0x50>
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
138: e5dd3004 ldrb r3, [sp, #4]
13c: e203300c and r3, r3, #12
140: e3530008 cmp r3, #8
144: 93002000 movwls r2, #0
148: 93402000 movtls r2, #0
14c: 97d20103 ldrbls r0, [r2, r3, lsl #2]
index = 3;
break;
}
return index;
}
150: e28dd00c add sp, sp, #12
154: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
158: e5950004 ldr r0, [r5, #4]
15c: e3001000 movw r1, #0
160: e1a02004 mov r2, r4
164: e3401000 movt r1, #0
168: e2800020 add r0, r0, #32
16c: ebfffffe bl 0 <dev_err>
170: e3a00002 mov r0, #2
index = 3;
break;
}
return index;
}
174: e28dd00c add sp, sp, #12
178: e8bd8030 pop {r4, r5, pc}
0000017c <si5351_clkout_recalc_rate>:
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
17c: e92d40f0 push {r4, r5, r6, r7, lr}
180: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
184: e5d03020 ldrb r3, [r0, #32]
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
188: e1a06001 mov r6, r1
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
rdiv = si5351_reg_read(hwdata->drvdata, reg);
18c: e590700c ldr r7, [r0, #12]
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
190: e1a05000 mov r5, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
194: e3530005 cmp r3, #5
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
198: e28d2004 add r2, sp, #4
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
19c: 91a04183 lslls r4, r3, #3
1a0: 9284402c addls r4, r4, #44 ; 0x2c
1a4: 83a0105c movhi r1, #92 ; 0x5c
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
1a8: e5970008 ldr r0, [r7, #8]
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
1ac: 81a04001 movhi r4, r1
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
1b0: 96ef4074 uxtbls r4, r4
1b4: 91a01004 movls r1, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
1b8: ebfffffe bl 0 <regmap_read>
if (ret) {
1bc: e3500000 cmp r0, #0
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
1c0: 05dd0004 ldrbeq r0, [sp, #4]
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
1c4: 1a000006 bne 1e4 <si5351_clkout_recalc_rate+0x68>
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
rdiv = si5351_reg_read(hwdata->drvdata, reg);
if (hwdata->num == 6) {
1c8: e5d53020 ldrb r3, [r5, #32]
1cc: e3530006 cmp r3, #6
rdiv &= SI5351_OUTPUT_CLK6_DIV_MASK;
1d0: 02000007 andeq r0, r0, #7
} else {
rdiv &= SI5351_OUTPUT_CLK_DIV_MASK;
rdiv >>= SI5351_OUTPUT_CLK_DIV_SHIFT;
1d4: 17e20250 ubfxne r0, r0, #4, #3
}
return parent_rate >> rdiv;
}
1d8: e1a00036 lsr r0, r6, r0
1dc: e28dd00c add sp, sp, #12
1e0: e8bd80f0 pop {r4, r5, r6, r7, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
1e4: e5970004 ldr r0, [r7, #4]
1e8: e3001000 movw r1, #0
1ec: e1a02004 mov r2, r4
1f0: e3401000 movt r1, #0
1f4: e2800020 add r0, r0, #32
1f8: ebfffffe bl 0 <dev_err>
"unable to read from reg%02x\n", reg);
return 0;
1fc: e3a00000 mov r0, #0
200: eafffff0 b 1c8 <si5351_clkout_recalc_rate+0x4c>
00000204 <si5351_clkout_round_rate>:
return parent_rate >> rdiv;
}
static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
204: e92d4030 push {r4, r5, lr}
208: e1a04002 mov r4, r2
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char rdiv;
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
20c: e5d03020 ldrb r3, [r0, #32]
return parent_rate >> rdiv;
}
static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
210: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char rdiv;
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
214: e3530005 cmp r3, #5
218: 9a000017 bls 27c <si5351_clkout_round_rate+0x78>
21c: e30d3180 movw r3, #53632 ; 0xd180
220: e34038f0 movt r3, #2288 ; 0x8f0
224: e1510003 cmp r1, r3
228: 21a01003 movcs r1, r3
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
22c: e3510d7d cmp r1, #8000 ; 0x1f40
230: 2a00003a bcs 320 <si5351_clkout_round_rate+0x11c>
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
234: e5900004 ldr r0, [r0, #4]
238: ebfffffe bl 0 <__clk_get_flags>
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
23c: e3a01d7d mov r1, #8000 ; 0x1f40
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
240: e3100004 tst r0, #4
244: 0a000015 beq 2a0 <si5351_clkout_round_rate+0x9c>
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
248: e304023f movw r0, #16959 ; 0x423f
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
24c: e3a03000 mov r3, #0
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
250: e340000f movt r0, #15
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
254: e2833001 add r3, r3, #1
rate *= 2;
258: e1a01081 lsl r1, r1, #1
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
25c: e6ef3073 uxtb r3, r3
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
260: e1510000 cmp r1, r0
264: 93530006 cmpls r3, #6
268: 9afffff9 bls 254 <si5351_clkout_round_rate+0x50>
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
26c: e1a00331 lsr r0, r1, r3
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
rate *= 2;
}
*parent_rate = rate;
270: e5841000 str r1, [r4]
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
}
274: e28dd00c add sp, sp, #12
278: e8bd8030 pop {r4, r5, pc}
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
27c: e3a05b1a mov r5, #26624 ; 0x6800
280: e3405989 movt r5, #2441 ; 0x989
284: e1510005 cmp r1, r5
288: 9affffe7 bls 22c <si5351_clkout_round_rate+0x28>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
28c: e5900004 ldr r0, [r0, #4]
290: ebfffffe bl 0 <__clk_get_flags>
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
294: e1a01005 mov r1, r5
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
298: e3100004 tst r0, #4
29c: 1a000029 bne 348 <si5351_clkout_round_rate+0x144>
} else {
unsigned long new_rate, new_err, err;
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
2a0: e5940000 ldr r0, [r4]
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2a4: e0613000 rsb r3, r1, r0
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
2a8: e1a0e0a0 lsr lr, r0, #1
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2ac: e3530000 cmp r3, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2b0: e061400e rsb r4, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2b4: b2633000 rsblt r3, r3, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2b8: e3540000 cmp r4, #0
2bc: b2644000 rsblt r4, r4, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2c0: e1530004 cmp r3, r4
2c4: 3a000012 bcc 314 <si5351_clkout_round_rate+0x110>
2c8: e3a03000 mov r3, #0
break;
rdiv++;
2cc: e2833001 add r3, r3, #1
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
2d0: e1a0e0ae lsr lr, lr, #1
new_err = abs(new_rate - rate);
2d4: e061200e rsb r2, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
break;
rdiv++;
2d8: e6ef3073 uxtb r3, r3
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2dc: e3520000 cmp r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2e0: e243c007 sub ip, r3, #7
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2e4: b2622000 rsblt r2, r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2e8: e16fcf1c clz ip, ip
2ec: e1a0c2ac lsr ip, ip, #5
2f0: e1520004 cmp r2, r4
2f4: 838cc001 orrhi ip, ip, #1
2f8: e1a04002 mov r4, r2
2fc: e35c0000 cmp ip, #0
300: 0afffff1 beq 2cc <si5351_clkout_round_rate+0xc8>
304: e1a01000 mov r1, r0
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
308: e1a00331 lsr r0, r1, r3
}
30c: e28dd00c add sp, sp, #12
310: e8bd8030 pop {r4, r5, pc}
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
314: e1a01000 mov r1, r0
318: e3a03000 mov r3, #0
31c: eafffff9 b 308 <si5351_clkout_round_rate+0x104>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
320: e5900004 ldr r0, [r0, #4]
324: e58d1004 str r1, [sp, #4]
328: ebfffffe bl 0 <__clk_get_flags>
32c: e3100004 tst r0, #4
330: e59d1004 ldr r1, [sp, #4]
334: 0affffd9 beq 2a0 <si5351_clkout_round_rate+0x9c>
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
338: e304323f movw r3, #16959 ; 0x423f
33c: e340300f movt r3, #15
340: e1510003 cmp r1, r3
344: 9affffbf bls 248 <si5351_clkout_round_rate+0x44>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
348: e3a03000 mov r3, #0
34c: eaffffc6 b 26c <si5351_clkout_round_rate+0x68>
00000350 <si5351_msynth_round_rate>:
return (unsigned long)rate;
}
static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
350: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
354: e1a06000 mov r6, r0
unsigned long long lltmp;
unsigned long a, b, c;
int divby4;
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
358: e5d03020 ldrb r3, [r0, #32]
return (unsigned long)rate;
}
static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
35c: e24dd014 sub sp, sp, #20
360: e1a05001 mov r5, r1
364: e1a09002 mov r9, r2
unsigned long long lltmp;
unsigned long a, b, c;
int divby4;
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
368: e3530005 cmp r3, #5
36c: 9a000024 bls 404 <si5351_msynth_round_rate+0xb4>
370: e30d3180 movw r3, #53632 ; 0xd180
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
374: e304123f movw r1, #16959 ; 0x423f
378: e34038f0 movt r3, #2288 ; 0x8f0
37c: e1550003 cmp r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
380: e3042240 movw r2, #16960 ; 0x4240
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
384: e340100f movt r1, #15
388: 21a05003 movcs r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
38c: e1550001 cmp r5, r1
390: e340200f movt r2, #15
394: 91a05002 movls r5, r2
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
398: e5960004 ldr r0, [r6, #4]
39c: ebfffffe bl 0 <__clk_get_flags>
3a0: e3100004 tst r0, #4
3a4: 0a000021 beq 430 <si5351_msynth_round_rate+0xe0>
* find largest integer divider for max
* vco frequency and given target rate
*/
if (divby4 == 0) {
lltmp = SI5351_PLL_VCO_MAX;
do_div(lltmp, rate);
3a8: e1a04005 mov r4, r5
3ac: e28f1f4b add r1, pc, #300 ; 0x12c
3b0: e1c100d0 ldrd r0, [r1]
3b4: e3a0a000 mov sl, #0
3b8: ebfffffe bl 0 <__do_div64>
3bc: e1a07002 mov r7, r2
a = 4;
b = 0;
c = 1;
*parent_rate = a * rate;
3c0: e0000795 mul r0, r5, r7
do_div(lltmp, rate);
a = (unsigned long)lltmp;
} else
a = 4;
b = 0;
3c4: e3a0b000 mov fp, #0
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
3c8: e1a04007 mov r4, r7
3cc: e1a0100b mov r1, fp
3d0: ebfffffe bl 0 <__do_div64>
rate = (unsigned long)lltmp;
/* calculate parameters */
if (divby4) {
3d4: e15a000b cmp sl, fp
a = (unsigned long)lltmp;
} else
a = 4;
b = 0;
c = 1;
3d8: e3a08001 mov r8, #1
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
3dc: e1a04002 mov r4, r2
a = 4;
b = 0;
c = 1;
*parent_rate = a * rate;
3e0: e5890000 str r0, [r9]
3e4: 01a0500a moveq r5, sl
lltmp *= c;
do_div(lltmp, a * c + b);
rate = (unsigned long)lltmp;
/* calculate parameters */
if (divby4) {
3e8: 0a00002d beq 4a4 <si5351_msynth_round_rate+0x154>
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
*parent_rate, rate);
//printk("parent_rate = %lu\n", *parent_rate);
return rate;
}
3ec: e1a00004 mov r0, r4
do_div(lltmp, a * c + b);
rate = (unsigned long)lltmp;
/* calculate parameters */
if (divby4) {
hwdata->params.p3 = 1;
3f0: e5868018 str r8, [r6, #24]
hwdata->params.p2 = 0;
3f4: e586b014 str fp, [r6, #20]
hwdata->params.p1 = 0;
3f8: e586b010 str fp, [r6, #16]
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
*parent_rate, rate);
//printk("parent_rate = %lu\n", *parent_rate);
return rate;
}
3fc: e28dd014 add sp, sp, #20
400: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
404: e3a03b1a mov r3, #26624 ; 0x6800
408: e3403989 movt r3, #2441 ; 0x989
40c: e1510003 cmp r1, r3
rate = SI5351_MULTISYNTH_MAX_FREQ;
410: 81a05003 movhi r5, r3
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
414: 9a000050 bls 55c <si5351_msynth_round_rate+0x20c>
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
418: e5960004 ldr r0, [r6, #4]
41c: ebfffffe bl 0 <__clk_get_flags>
420: e3100004 tst r0, #4
} else {
unsigned long rfrac, denom;
/* disable divby4 */
if (divby4) {
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
424: 030d5180 movweq r5, #53632 ; 0xd180
428: 034058f0 movteq r5, #2288 ; 0x8f0
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
42c: 1a000033 bne 500 <si5351_msynth_round_rate+0x1b0>
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
430: e5998000 ldr r8, [r9]
434: e1a01005 mov r1, r5
438: e1a00008 mov r0, r8
43c: ebfffffe bl 0 <__aeabi_uidiv>
if (a < SI5351_MULTISYNTH_A_MIN)
440: e3500005 cmp r0, #5
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
444: e1a07000 mov r7, r0
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
448: 93a07006 movls r7, #6
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
44c: 8a000025 bhi 4e8 <si5351_msynth_round_rate+0x198>
else if (a > SI5351_MULTISYNTH_A_MAX)
a = SI5351_MULTISYNTH_A_MAX;
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
450: e1a01005 mov r1, r5
454: e1a00008 mov r0, r8
458: ebfffffe bl 0 <__aeabi_uidivmod>
lltmp *= denom;
do_div(lltmp, rate);
45c: e304b240 movw fp, #16960 ; 0x4240
460: e340b00f movt fp, #15
rfrac = (unsigned long)lltmp;
b = 0;
464: e3a03000 mov r3, #0
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
468: e1a04005 mov r4, r5
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
46c: e3a0a001 mov sl, #1
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
470: e0810b91 umull r0, r1, r1, fp
rfrac = (unsigned long)lltmp;
b = 0;
474: e58d3008 str r3, [sp, #8]
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
478: ebfffffe bl 0 <__do_div64>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
47c: e2520000 subs r0, r2, #0
lltmp *= denom;
do_div(lltmp, rate);
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
480: e58da00c str sl, [sp, #12]
if (rfrac)
484: 1a000020 bne 50c <si5351_msynth_round_rate+0x1bc>
488: e1a03008 mov r3, r8
48c: e1a05000 mov r5, r0
490: e1a0800a mov r8, sl
494: e1a04007 mov r4, r7
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
498: e0810a93 umull r0, r1, r3, sl
49c: ebfffffe bl 0 <__do_div64>
4a0: e1a04002 mov r4, r2
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
4a4: e1a05385 lsl r5, r5, #7
if (divby4) {
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
4a8: e5868018 str r8, [r6, #24]
hwdata->params.p2 = (128 * b) % c;
4ac: e1a01008 mov r1, r8
4b0: e1a00005 mov r0, r5
4b4: ebfffffe bl 0 <__aeabi_uidivmod>
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
4b8: e1a00005 mov r0, r5
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
4bc: e5861014 str r1, [r6, #20]
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
4c0: e1a01008 mov r1, r8
4c4: ebfffffe bl 0 <__aeabi_uidiv>
4c8: e2400c02 sub r0, r0, #512 ; 0x200
4cc: e0807387 add r7, r0, r7, lsl #7
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
*parent_rate, rate);
//printk("parent_rate = %lu\n", *parent_rate);
return rate;
}
4d0: e1a00004 mov r0, r4
} else {
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
4d4: e5867010 str r7, [r6, #16]
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
*parent_rate, rate);
//printk("parent_rate = %lu\n", *parent_rate);
return rate;
}
4d8: e28dd014 add sp, sp, #20
4dc: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
4e0: 35a4e900 .word 0x35a4e900
4e4: 00000000 .word 0x00000000
/* determine integer part of divider equation */
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
4e8: e5d63020 ldrb r3, [r6, #32]
4ec: e3530005 cmp r3, #5
4f0: 9a000015 bls 54c <si5351_msynth_round_rate+0x1fc>
a = SI5351_MULTISYNTH67_A_MAX;
4f4: e35700ff cmp r7, #255 ; 0xff
4f8: 23a070fe movcs r7, #254 ; 0xfe
4fc: eaffffd3 b 450 <si5351_msynth_round_rate+0x100>
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
rate = SI5351_MULTISYNTH_MIN_FREQ;
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
500: e3a0a001 mov sl, #1
if (divby4 == 0) {
lltmp = SI5351_PLL_VCO_MAX;
do_div(lltmp, rate);
a = (unsigned long)lltmp;
} else
a = 4;
504: e3a07004 mov r7, #4
508: eaffffac b 3c0 <si5351_msynth_round_rate+0x70>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
rational_best_approximation(rfrac, denom,
50c: e30f3fff movw r3, #65535 ; 0xffff
510: e30f2ffe movw r2, #65534 ; 0xfffe
514: e28dc00c add ip, sp, #12
518: e340300f movt r3, #15
51c: e58dc004 str ip, [sp, #4]
520: e1a0100b mov r1, fp
524: e28dc008 add ip, sp, #8
528: e340200f movt r2, #15
52c: e58dc000 str ip, [sp]
530: ebfffffe bl 0 <rational_best_approximation>
534: e5993000 ldr r3, [r9]
538: e59d800c ldr r8, [sp, #12]
53c: e59d5008 ldr r5, [sp, #8]
540: e1a0a008 mov sl, r8
544: e0245897 mla r4, r7, r8, r5
548: eaffffd2 b 498 <si5351_msynth_round_rate+0x148>
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
a = SI5351_MULTISYNTH67_A_MAX;
else if (a > SI5351_MULTISYNTH_A_MAX)
54c: e3003708 movw r3, #1800 ; 0x708
a = SI5351_MULTISYNTH_A_MAX;
550: e1570003 cmp r7, r3
554: 21a07003 movcs r7, r3
558: eaffffbc b 450 <si5351_msynth_round_rate+0x100>
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
55c: e304323f movw r3, #16959 ; 0x423f
560: e340300f movt r3, #15
564: e1550003 cmp r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
568: 93045240 movwls r5, #16960 ; 0x4240
56c: 9340500f movtls r5, #15
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
570: 9affff88 bls 398 <si5351_msynth_round_rate+0x48>
rate = SI5351_MULTISYNTH_MIN_FREQ;
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
574: e30d3180 movw r3, #53632 ; 0xd180
578: e34038f0 movt r3, #2288 ; 0x8f0
57c: e1550003 cmp r5, r3
580: 8affffa4 bhi 418 <si5351_msynth_round_rate+0xc8>
584: eaffff83 b 398 <si5351_msynth_round_rate+0x48>
00000588 <si5351_pll_round_rate>:
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
588: e30435ff movw r3, #17919 ; 0x45ff
58c: e34233c3 movt r3, #9155 ; 0x23c3
590: e1510003 cmp r1, r3
return (unsigned long)rate;
}
static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
594: e92d47f0 push {r4, r5, r6, r7, r8, r9, sl, lr}
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
rate = SI5351_PLL_VCO_MIN;
598: 93a05c46 movls r5, #17920 ; 0x4600
return (unsigned long)rate;
}
static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
59c: e24dd010 sub sp, sp, #16
5a0: e1a07000 mov r7, r0
5a4: e1a08002 mov r8, r2
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
rate = SI5351_PLL_VCO_MIN;
5a8: 934253c3 movtls r5, #9155 ; 0x23c3
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
5ac: 9a000004 bls 5c4 <si5351_pll_round_rate+0x3c>
rate = SI5351_PLL_VCO_MIN;
if (rate > SI5351_PLL_VCO_MAX)
rate = SI5351_PLL_VCO_MAX;
5b0: e3a03ce9 mov r3, #59648 ; 0xe900
5b4: e1a05001 mov r5, r1
5b8: e34335a4 movt r3, #13732 ; 0x35a4
5bc: e1510003 cmp r1, r3
5c0: 21a05003 movcs r5, r3
/* determine integer part of feedback equation */
a = rate / *parent_rate;
5c4: e5984000 ldr r4, [r8]
5c8: e1a00005 mov r0, r5
5cc: e1a01004 mov r1, r4
5d0: ebfffffe bl 0 <__aeabi_uidiv>
if (a < SI5351_PLL_A_MIN)
5d4: e350000e cmp r0, #14
rate = SI5351_PLL_VCO_MIN;
if (rate > SI5351_PLL_VCO_MAX)
rate = SI5351_PLL_VCO_MAX;
/* determine integer part of feedback equation */
a = rate / *parent_rate;
5d8: e1a06000 mov r6, r0
if (a < SI5351_PLL_A_MIN)
rate = *parent_rate * SI5351_PLL_A_MIN;
5dc: 90645204 rsbls r5, r4, r4, lsl #4
rate = SI5351_PLL_VCO_MAX;
/* determine integer part of feedback equation */
a = rate / *parent_rate;
if (a < SI5351_PLL_A_MIN)
5e0: 9a000002 bls 5f0 <si5351_pll_round_rate+0x68>
rate = *parent_rate * SI5351_PLL_A_MIN;
if (a > SI5351_PLL_A_MAX)
5e4: e350005a cmp r0, #90 ; 0x5a
rate = *parent_rate * SI5351_PLL_A_MAX;
5e8: 83a0505a movhi r5, #90 ; 0x5a
5ec: 80050495 mulhi r5, r5, r4
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
5f0: e1a00005 mov r0, r5
5f4: e1a01004 mov r1, r4
lltmp *= denom;
do_div(lltmp, *parent_rate);
5f8: e3049240 movw r9, #16960 ; 0x4240
if (a > SI5351_PLL_A_MAX)
rate = *parent_rate * SI5351_PLL_A_MAX;
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
5fc: ebfffffe bl 0 <__aeabi_uidivmod>
lltmp *= denom;
do_div(lltmp, *parent_rate);
600: e340900f movt r9, #15
rfrac = (unsigned long)lltmp;
b = 0;
604: e3a03000 mov r3, #0
c = 1;
608: e3a05001 mov r5, #1
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
lltmp *= denom;
do_div(lltmp, *parent_rate);
60c: e0810991 umull r0, r1, r1, r9
rfrac = (unsigned long)lltmp;
b = 0;
610: e58d3008 str r3, [sp, #8]
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
lltmp *= denom;
do_div(lltmp, *parent_rate);
614: ebfffffe bl 0 <__do_div64>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
618: e2520000 subs r0, r2, #0
lltmp *= denom;
do_div(lltmp, *parent_rate);
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
61c: e58d500c str r5, [sp, #12]
if (rfrac)
620: 1a00000e bne 660 <si5351_pll_round_rate+0xd8>
624: e1a02000 mov r2, r0
628: e3a00cfe mov r0, #65024 ; 0xfe00
62c: e1a04005 mov r4, r5
630: e1a09002 mov r9, r2
634: e34f0fff movt r0, #65535 ; 0xffff
/* calculate parameters */
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
638: e0800386 add r0, r0, r6, lsl #7
if (rfrac)
rational_best_approximation(rfrac, denom,
SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);
/* calculate parameters */
hwdata->params.p3 = c;
63c: e5874018 str r4, [r7, #24]
hwdata->params.p2 = (128 * b) % c;
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
640: e5870010 str r0, [r7, #16]
rational_best_approximation(rfrac, denom,
SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);
/* calculate parameters */
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
644: e5879014 str r9, [r7, #20]
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
/* recalculate rate by fIN * (a + b/c) */
lltmp = *parent_rate;
lltmp *= b;
648: e5985000 ldr r5, [r8]
do_div(lltmp, c);
64c: e0810295 umull r0, r1, r5, r2
650: ebfffffe bl 0 <__do_div64>
"%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), a, b, c,
*parent_rate, rate);
return rate;
}
654: e0202695 mla r0, r5, r6, r2
658: e28dd010 add sp, sp, #16
65c: e8bd87f0 pop {r4, r5, r6, r7, r8, r9, sl, pc}
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
rational_best_approximation(rfrac, denom,
660: e30f3fff movw r3, #65535 ; 0xffff
664: e30f2ffe movw r2, #65534 ; 0xfffe
668: e340200f movt r2, #15
66c: e28de00c add lr, sp, #12
670: e28dc008 add ip, sp, #8
674: e1a01009 mov r1, r9
678: e340300f movt r3, #15
67c: e88d5000 stm sp, {ip, lr}
680: ebfffffe bl 0 <rational_best_approximation>
684: e59d5008 ldr r5, [sp, #8]
688: e59d400c ldr r4, [sp, #12]
68c: e1a0a385 lsl sl, r5, #7
690: e1a01004 mov r1, r4
694: e1a0000a mov r0, sl
698: ebfffffe bl 0 <__aeabi_uidivmod>
69c: e1a0000a mov r0, sl
6a0: e1a09001 mov r9, r1
6a4: e1a01004 mov r1, r4
6a8: ebfffffe bl 0 <__aeabi_uidiv>
6ac: e1a02005 mov r2, r5
6b0: e2400c02 sub r0, r0, #512 ; 0x200
6b4: eaffffdf b 638 <si5351_pll_round_rate+0xb0>
000006b8 <si5351_vxco_prepare>:
/*
* Si5351 vxco clock input (Si5351B only)
*/
static int si5351_vxco_prepare(struct clk_hw *hw)
{
6b8: e92d4010 push {r4, lr}
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
dev_warn(&hwdata->drvdata->client->dev, "VXCO currently unsupported\n");
6bc: e3001000 movw r1, #0
6c0: e590300c ldr r3, [r0, #12]
6c4: e3401000 movt r1, #0
6c8: e5930004 ldr r0, [r3, #4]
6cc: e2800020 add r0, r0, #32
6d0: ebfffffe bl 0 <dev_warn>
return 0;
}
6d4: e3a00000 mov r0, #0
6d8: e8bd8010 pop {r4, pc}
000006dc <si5351_xtal_prepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
6dc: e3a03040 mov r3, #64 ; 0x40
6e0: e3a010bb mov r1, #187 ; 0xbb
/*
* Si5351 xtal clock input
*/
static int si5351_xtal_prepare(struct clk_hw *hw)
{
6e4: e92d4010 push {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
6e8: e1a02003 mov r2, r3
6ec: e5100014 ldr r0, [r0, #-20] ; 0xffffffec
6f0: ebfffffe bl 0 <regmap_update_bits>
struct si5351_driver_data *drvdata =
container_of(hw, struct si5351_driver_data, xtal);
si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
SI5351_XTAL_ENABLE, SI5351_XTAL_ENABLE);
return 0;
}
6f4: e3a00000 mov r0, #0
6f8: e8bd8010 pop {r4, pc}
000006fc <si5351_xtal_unprepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
6fc: e5100014 ldr r0, [r0, #-20] ; 0xffffffec
700: e3a03000 mov r3, #0
704: e3a02040 mov r2, #64 ; 0x40
708: e3a010bb mov r1, #187 ; 0xbb
70c: eafffffe b 0 <regmap_update_bits>
00000710 <si5351_clkin_prepare>:
710: e3a03080 mov r3, #128 ; 0x80
714: e3a010bb mov r1, #187 ; 0xbb
/*
* Si5351 clkin clock input (Si5351C only)
*/
static int si5351_clkin_prepare(struct clk_hw *hw)
{
718: e92d4010 push {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
71c: e1a02003 mov r2, r3
720: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
724: ebfffffe bl 0 <regmap_update_bits>
struct si5351_driver_data *drvdata =
container_of(hw, struct si5351_driver_data, clkin);
si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
SI5351_CLKIN_ENABLE, SI5351_CLKIN_ENABLE);
return 0;
}
728: e3a00000 mov r0, #0
72c: e8bd8010 pop {r4, pc}
00000730 <si5351_clkin_unprepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
730: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
734: e3a03000 mov r3, #0
738: e3a02080 mov r2, #128 ; 0x80
73c: e3a010bb mov r1, #187 ; 0xbb
740: eafffffe b 0 <regmap_update_bits>
00000744 <si5351_clkin_recalc_rate>:
container_of(hw, struct si5351_driver_data, clkin);
unsigned long rate;
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
744: e3a03b1a mov r3, #26624 ; 0x6800
748: e3403989 movt r3, #2441 ; 0x989
74c: e1510003 cmp r1, r3
* The input frequency range of the PLL is 10Mhz to 40MHz.
* If CLKIN is >40MHz, the input divider must be used.
*/
static unsigned long si5351_clkin_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
750: e92d4010 push {r4, lr}
754: 83a030c0 movhi r3, #192 ; 0xc0
758: e1a04001 mov r4, r1
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
75c: 81a041a1 lsrhi r4, r1, #3
container_of(hw, struct si5351_driver_data, clkin);
unsigned long rate;
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
760: 8a00000b bhi 794 <si5351_clkin_recalc_rate+0x50>
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
} else if (parent_rate > 80000000) {
764: e3a03b2d mov r3, #46080 ; 0xb400
768: e34034c4 movt r3, #1220 ; 0x4c4
76c: e1540003 cmp r4, r3
idiv = SI5351_CLKIN_DIV_4;
rate /= 4;
770: 81a04124 lsrhi r4, r4, #2
774: 83a03080 movhi r3, #128 ; 0x80
rate = parent_rate;
if (parent_rate > 160000000) {
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
} else if (parent_rate > 80000000) {
778: 8a000005 bhi 794 <si5351_clkin_recalc_rate+0x50>
idiv = SI5351_CLKIN_DIV_4;
rate /= 4;
} else if (parent_rate > 40000000) {
77c: e3a03c5a mov r3, #23040 ; 0x5a00
780: e3403262 movt r3, #610 ; 0x262
784: e1540003 cmp r4, r3
idiv = SI5351_CLKIN_DIV_2;
rate /= 2;
788: 81a040a4 lsrhi r4, r4, #1
78c: 83a03040 movhi r3, #64 ; 0x40
790: 93a03000 movls r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
794: e3a020c0 mov r2, #192 ; 0xc0
798: e3a0100f mov r1, #15
79c: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
7a0: ebfffffe bl 0 <regmap_update_bits>
dev_dbg(&drvdata->client->dev, "%s - clkin div = %d, rate = %lu\n",
__func__, (1 << (idiv >> 6)), rate);
return rate;
}
7a4: e1a00004 mov r0, r4
7a8: e8bd8010 pop {r4, pc}
000007ac <si5351_clkout_prepare>:
return 0;
}
static int si5351_clkout_prepare(struct clk_hw *hw)
{
7ac: e92d4010 push {r4, lr}
7b0: e1a04000 mov r4, r0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
7b4: e5d01020 ldrb r1, [r0, #32]
7b8: e3a03000 mov r3, #0
7bc: e590000c ldr r0, [r0, #12]
7c0: e3a02080 mov r2, #128 ; 0x80
7c4: e2811010 add r1, r1, #16
7c8: e5900008 ldr r0, [r0, #8]
7cc: e6ef1071 uxtb r1, r1
7d0: ebfffffe bl 0 <regmap_update_bits>
7d4: e5d42020 ldrb r2, [r4, #32]
7d8: e594000c ldr r0, [r4, #12]
7dc: e3a03001 mov r3, #1
7e0: e1a02213 lsl r2, r3, r2
7e4: e3a01003 mov r1, #3
7e8: e3a03000 mov r3, #0
7ec: e6ef2072 uxtb r2, r2
7f0: e5900008 ldr r0, [r0, #8]
7f4: ebfffffe bl 0 <regmap_update_bits>
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
SI5351_CLK_POWERDOWN, 0);
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), 0);
return 0;
}
7f8: e3a00000 mov r0, #0
7fc: e8bd8010 pop {r4, pc}
00000800 <si5351_clkout_unprepare>:
static void si5351_clkout_unprepare(struct clk_hw *hw)
{
800: e92d4010 push {r4, lr}
804: e1a04000 mov r4, r0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
808: e5d01020 ldrb r1, [r0, #32]
80c: e3a03080 mov r3, #128 ; 0x80
810: e590000c ldr r0, [r0, #12]
814: e1a02003 mov r2, r3
818: e2811010 add r1, r1, #16
81c: e5900008 ldr r0, [r0, #8]
820: e6ef1071 uxtb r1, r1
824: ebfffffe bl 0 <regmap_update_bits>
828: e5d41020 ldrb r1, [r4, #32]
82c: e3a03001 mov r3, #1
830: e594200c ldr r2, [r4, #12]
834: e1a03113 lsl r3, r3, r1
838: e3a01003 mov r1, #3
83c: e6ef3073 uxtb r3, r3
840: e5920008 ldr r0, [r2, #8]
844: e1a02003 mov r2, r3
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN);
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), (1 << hwdata->num));
}
848: e8bd4010 pop {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
84c: eafffffe b 0 <regmap_update_bits>
00000850 <si5351_clkout_set_rate>:
return rate;
}
static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
850: e92d4010 push {r4, lr}
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
854: e1a0e0a2 lsr lr, r2, #1
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
858: e0612002 rsb r2, r1, r2
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
85c: e061c00e rsb ip, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
860: e3520000 cmp r2, #0
return rate;
}
static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
864: e1a04000 mov r4, r0
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
868: b2622000 rsblt r2, r2, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
86c: e35c0000 cmp ip, #0
870: b26cc000 rsblt ip, ip, #0
container_of(hw, struct si5351_hw_data, hw);
unsigned long new_rate, new_err, err;
unsigned char rdiv;
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
874: e3a03000 mov r3, #0
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
878: e152000c cmp r2, ip
87c: 3a00000d bcc 8b8 <si5351_clkout_set_rate+0x68>
break;
rdiv++;
880: e2833001 add r3, r3, #1
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
884: e1a0e0ae lsr lr, lr, #1
new_err = abs(new_rate - rate);
888: e061200e rsb r2, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
break;
rdiv++;
88c: e6ef3073 uxtb r3, r3
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
890: e3520000 cmp r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
894: e2430007 sub r0, r3, #7
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
898: b2622000 rsblt r2, r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
89c: e16f0f10 clz r0, r0
8a0: e1a002a0 lsr r0, r0, #5
8a4: e152000c cmp r2, ip
8a8: 83800001 orrhi r0, r0, #1
8ac: e1a0c002 mov ip, r2
8b0: e3500000 cmp r0, #0
8b4: 0afffff1 beq 880 <si5351_clkout_set_rate+0x30>
rdiv++;
err = new_err;
} while (1);
/* write output divider */
switch (hwdata->num) {
8b8: e5d42020 ldrb r2, [r4, #32]
8bc: e3520006 cmp r2, #6
8c0: 0a000020 beq 948 <si5351_clkout_set_rate+0xf8>
8c4: e3520007 cmp r2, #7
8c8: 0a000016 beq 928 <si5351_clkout_set_rate+0xd8>
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
8cc: e3520005 cmp r2, #5
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
SI5351_OUTPUT_CLK_DIV_MASK,
rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
break;
default:
si5351_set_bits(hwdata->drvdata,
8d0: e594000c ldr r0, [r4, #12]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
8d4: d1a01182 lslle r1, r2, #3
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
8d8: c2821054 addgt r1, r2, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
8dc: d281102a addle r1, r1, #42 ; 0x2a
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
8e0: e1a03203 lsl r3, r3, #4
8e4: e20330f0 and r3, r3, #240 ; 0xf0
8e8: e5900008 ldr r0, [r0, #8]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
8ec: e6ef1071 uxtb r1, r1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
8f0: e3a02070 mov r2, #112 ; 0x70
8f4: e2811002 add r1, r1, #2
8f8: e6ef1071 uxtb r1, r1
8fc: ebfffffe bl 0 <regmap_update_bits>
900: e5d41020 ldrb r1, [r4, #32]
904: e3a03000 mov r3, #0
908: e594000c ldr r0, [r4, #12]
90c: e3a02080 mov r2, #128 ; 0x80
910: e2811010 add r1, r1, #16
914: e5900008 ldr r0, [r0, #8]
918: e6ef1071 uxtb r1, r1
91c: ebfffffe bl 0 <regmap_update_bits>
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
parent_rate, rate);
return 0;
}
920: e3a00000 mov r0, #0
924: e8bd8010 pop {r4, pc}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
928: e594000c ldr r0, [r4, #12]
92c: e1a03203 lsl r3, r3, #4
930: e20330f0 and r3, r3, #240 ; 0xf0
934: e3a02070 mov r2, #112 ; 0x70
938: e3a0105c mov r1, #92 ; 0x5c
93c: e5900008 ldr r0, [r0, #8]
940: ebfffffe bl 0 <regmap_update_bits>
944: eaffffed b 900 <si5351_clkout_set_rate+0xb0>
948: e594000c ldr r0, [r4, #12]
94c: e3a02007 mov r2, #7
950: e3a0105c mov r1, #92 ; 0x5c
954: e5900008 ldr r0, [r0, #8]
958: ebfffffe bl 0 <regmap_update_bits>
95c: eaffffe7 b 900 <si5351_clkout_set_rate+0xb0>
00000960 <si5351_read_parameters.isra.0>:
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
960: e92d40f0 push {r4, r5, r6, r7, lr}
964: e1a05002 mov r5, r2
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
968: e242205a sub r2, r2, #90 ; 0x5a
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
96c: e1a06000 mov r6, r0
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
970: e3520001 cmp r2, #1
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
974: e24dd00c sub sp, sp, #12
978: e1a00001 mov r0, r1
97c: e1a04003 mov r4, r3
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
980: 8a00000d bhi 9bc <si5351_read_parameters.isra.0+0x5c>
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
984: e1a0200d mov r2, sp
988: e1a01005 mov r1, r5
98c: ebfffffe bl 0 <regmap_read>
if (ret) {
990: e3500000 cmp r0, #0
994: 05dd3000 ldrbeq r3, [sp]
998: 1a000022 bne a28 <si5351_read_parameters.isra.0+0xc8>
switch (reg) {
case SI5351_CLK6_PARAMETERS:
case SI5351_CLK7_PARAMETERS:
buf[0] = si5351_reg_read(drvdata, reg);
params->p1 = buf[0];
99c: e5843000 str r3, [r4]
params->p2 = 0;
params->p3 = 1;
9a0: e3a02000 mov r2, #0
9a4: e3a03001 mov r3, #1
9a8: e984000c stmib r4, {r2, r3}
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
9ac: e3a03001 mov r3, #1
9b0: e584300c str r3, [r4, #12]
}
9b4: e28dd00c add sp, sp, #12
9b8: e8bd80f0 pop {r4, r5, r6, r7, pc}
}
static inline int si5351_bulk_read(struct si5351_driver_data *drvdata,
u8 reg, u8 count, u8 *buf)
{
return regmap_bulk_read(drvdata->regmap, reg, buf, count);
9bc: e1a01005 mov r1, r5
9c0: e3a03008 mov r3, #8
9c4: e1a0200d mov r2, sp
9c8: ebfffffe bl 0 <regmap_bulk_read>
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
9cc: e5dd5005 ldrb r5, [sp, #5]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9d0: e5dd0003 ldrb r0, [sp, #3]
9d4: e5dde002 ldrb lr, [sp, #2]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
9d8: e205600f and r6, r5, #15
9dc: e5dd7006 ldrb r7, [sp, #6]
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
9e0: e20550f0 and r5, r5, #240 ; 0xf0
9e4: e5dd3000 ldrb r3, [sp]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9e8: e20ee003 and lr, lr, #3
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
9ec: e5dd2001 ldrb r2, [sp, #1]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9f0: e5ddc004 ldrb ip, [sp, #4]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
9f4: e5dd1007 ldrb r1, [sp, #7]
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
9f8: e1823403 orr r3, r2, r3, lsl #8
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9fc: e18c0400 orr r0, ip, r0, lsl #8
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a00: e1833605 orr r3, r3, r5, lsl #12
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
a04: e1811407 orr r1, r1, r7, lsl #8
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a08: e180080e orr r0, r0, lr, lsl #16
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
a0c: e1812806 orr r2, r1, r6, lsl #16
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a10: e5840000 str r0, [r4]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a14: e984000c stmib r4, {r2, r3}
}
params->valid = 1;
a18: e3a03001 mov r3, #1
a1c: e584300c str r3, [r4, #12]
}
a20: e28dd00c add sp, sp, #12
a24: e8bd80f0 pop {r4, r5, r6, r7, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
a28: e5960000 ldr r0, [r6]
a2c: e3001000 movw r1, #0
a30: e1a02005 mov r2, r5
a34: e3401000 movt r1, #0
a38: e2800020 add r0, r0, #32
a3c: ebfffffe bl 0 <dev_err>
a40: e3a03000 mov r3, #0
a44: eaffffd4 b 99c <si5351_read_parameters.isra.0+0x3c>
00000a48 <si5351_msynth_recalc_rate>:
SI5351_MULTISYNTH_SRC_VCO1);
}
static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
a48: e92d43f0 push {r4, r5, r6, r7, r8, r9, lr}
a4c: e1a06000 mov r6, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
a50: e5d03020 ldrb r3, [r0, #32]
SI5351_MULTISYNTH_SRC_VCO1);
}
static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
a54: e24dd00c sub sp, sp, #12
a58: e1a04001 mov r4, r1
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
a5c: e3530005 cmp r3, #5
return SI5351_CLK6_PARAMETERS + (num - 6);
a60: c2833054 addgt r3, r3, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
a64: d1a05183 lslle r5, r3, #3
a68: d285502a addle r5, r5, #42 ; 0x2a
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
a6c: c6ef5073 uxtbgt r5, r3
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
a70: e590301c ldr r3, [r0, #28]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
a74: d6ef5075 uxtble r5, r5
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
a78: e3530000 cmp r3, #0
a7c: 0a000013 beq ad0 <si5351_msynth_recalc_rate+0x88>
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
a80: e5963018 ldr r3, [r6, #24]
a84: e3530000 cmp r3, #0
a88: 0a00000d beq ac4 <si5351_msynth_recalc_rate+0x7c>
/*
* multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
a8c: e5d63020 ldrb r3, [r6, #32]
/*
* multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
a90: e1a08004 mov r8, r4
a94: e3a09000 mov r9, #0
if (hwdata->num > 5) {
a98: e3530005 cmp r3, #5
a9c: 9a000012 bls aec <si5351_msynth_recalc_rate+0xa4>
m = hwdata->params.p1;
aa0: e5964010 ldr r4, [r6, #16]
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
}
if (m == 0)
aa4: e3540000 cmp r4, #0
aa8: 0a000005 beq ac4 <si5351_msynth_recalc_rate+0x7c>
return 0;
do_div(rate, m);
aac: e1a00008 mov r0, r8
ab0: e1a01009 mov r1, r9
ab4: ebfffffe bl 0 <__do_div64>
ab8: e1a00002 mov r0, r2
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
m, parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
abc: e28dd00c add sp, sp, #12
ac0: e8bd83f0 pop {r4, r5, r6, r7, r8, r9, pc}
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
}
if (m == 0)
return 0;
ac4: e1a00004 mov r0, r4
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
m, parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
ac8: e28dd00c add sp, sp, #12
acc: e8bd83f0 pop {r4, r5, r6, r7, r8, r9, pc}
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
ad0: e590100c ldr r1, [r0, #12]
ad4: e2803010 add r3, r0, #16
ad8: e1a02005 mov r2, r5
adc: e2810004 add r0, r1, #4
ae0: e5911008 ldr r1, [r1, #8]
ae4: ebffff9d bl 960 <si5351_read_parameters.isra.0>
ae8: eaffffe4 b a80 <si5351_msynth_recalc_rate+0x38>
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
aec: e2855002 add r5, r5, #2
af0: e596700c ldr r7, [r6, #12]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
af4: e28d2004 add r2, sp, #4
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
af8: e6ef5075 uxtb r5, r5
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
afc: e5970008 ldr r0, [r7, #8]
b00: e1a01005 mov r1, r5
b04: ebfffffe bl 0 <regmap_read>
if (ret) {
b08: e3500000 cmp r0, #0
b0c: 1a00000b bne b40 <si5351_msynth_recalc_rate+0xf8>
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
b10: e5dd3004 ldrb r3, [sp, #4]
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
b14: e203300c and r3, r3, #12
b18: e353000c cmp r3, #12
b1c: 0a00000e beq b5c <si5351_msynth_recalc_rate+0x114>
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b20: e5962018 ldr r2, [r6, #24]
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b24: e5963010 ldr r3, [r6, #16]
b28: e5960014 ldr r0, [r6, #20]
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b2c: e1a08382 lsl r8, r2, #7
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b30: e2833c02 add r3, r3, #512 ; 0x200
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b34: e0898894 umull r8, r9, r4, r8
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b38: e0240392 mla r4, r2, r3, r0
b3c: eaffffd8 b aa4 <si5351_msynth_recalc_rate+0x5c>
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
b40: e5970004 ldr r0, [r7, #4]
b44: e3001000 movw r1, #0
b48: e1a02005 mov r2, r5
b4c: e3401000 movt r1, #0
b50: e2800020 add r0, r0, #32
b54: ebfffffe bl 0 <dev_err>
b58: eafffff0 b b20 <si5351_msynth_recalc_rate+0xd8>
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
b5c: e3a04004 mov r4, #4
b60: eaffffd1 b aac <si5351_msynth_recalc_rate+0x64>
00000b64 <si5351_pll_recalc_rate>:
SI5351_PLL_SRC_CLKIN);
}
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
b64: e92d41f0 push {r4, r5, r6, r7, r8, lr}
b68: e1a04000 mov r4, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
b6c: e5d02020 ldrb r2, [r0, #32]
SI5351_PLL_SRC_CLKIN);
}
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
b70: e1a05001 mov r5, r1
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
b74: e590301c ldr r3, [r0, #28]
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
b78: e3520000 cmp r2, #0
b7c: 03a0201a moveq r2, #26
b80: 13a02022 movne r2, #34 ; 0x22
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
b84: e3530000 cmp r3, #0
b88: 0a000013 beq bdc <si5351_pll_recalc_rate+0x78>
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
b8c: e5943018 ldr r3, [r4, #24]
b90: e3530000 cmp r3, #0
b94: 0a00000e beq bd4 <si5351_pll_recalc_rate+0x70>
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
b98: e5942010 ldr r2, [r4, #16]
rate += 512 * hwdata->params.p3;
b9c: e1a06483 lsl r6, r3, #9
rate += hwdata->params.p2;
rate *= parent_rate;
ba0: e5941014 ldr r1, [r4, #20]
do_div(rate, 128 * hwdata->params.p3);
ba4: e1a04383 lsl r4, r3, #7
if (hwdata->params.p3 == 0)
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
rate += 512 * hwdata->params.p3;
ba8: e3a07000 mov r7, #0
if (hwdata->params.p3 == 0)
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
bac: e0030392 mul r3, r2, r3
rate += 512 * hwdata->params.p3;
bb0: e0966003 adds r6, r6, r3
bb4: e2a77000 adc r7, r7, #0
rate += hwdata->params.p2;
rate *= parent_rate;
bb8: e0966001 adds r6, r6, r1
bbc: e2a77000 adc r7, r7, #0
bc0: e0810596 umull r0, r1, r6, r5
bc4: e0211795 mla r1, r5, r7, r1
do_div(rate, 128 * hwdata->params.p3);
bc8: ebfffffe bl 0 <__do_div64>
bcc: e1a00002 mov r0, r2
"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, (unsigned long)rate);
return (unsigned long)rate;
bd0: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
return parent_rate;
bd4: e1a00005 mov r0, r5
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
bd8: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
bdc: e590100c ldr r1, [r0, #12]
be0: e2803010 add r3, r0, #16
be4: e2810004 add r0, r1, #4
be8: e5911008 ldr r1, [r1, #8]
bec: ebffff5b bl 960 <si5351_read_parameters.isra.0>
bf0: eaffffe5 b b8c <si5351_pll_recalc_rate+0x28>
00000bf4 <si5351_write_parameters.isra.1>:
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
bf4: e92d41f0 push {r4, r5, r6, r7, r8, lr}
bf8: e1a06002 mov r6, r2
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
bfc: e242205a sub r2, r2, #90 ; 0x5a
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
c00: e24dd010 sub sp, sp, #16
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
c04: e3520001 cmp r2, #1
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
c08: e1a07001 mov r7, r1
c0c: e1a05003 mov r5, r3
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
c10: 9a000025 bls cac <si5351_write_parameters.isra.1+0xb8>
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
c14: e2864002 add r4, r6, #2
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c18: e5933008 ldr r3, [r3, #8]
c1c: e1a08000 mov r8, r0
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c20: e28d2004 add r2, sp, #4
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
c24: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c28: e5910000 ldr r0, [r1]
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c2c: e7e7c453 ubfx ip, r3, #8, #8
buf[1] = params->p3 & 0xff;
c30: e5cd3009 strb r3, [sp, #9]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c34: e1a01004 mov r1, r4
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c38: e5cdc008 strb ip, [sp, #8]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c3c: ebfffffe bl 0 <regmap_read>
if (ret) {
c40: e3500000 cmp r0, #0
c44: 059d4004 ldreq r4, [sp, #4]
c48: 020480fc andeq r8, r4, #252 ; 0xfc
c4c: 1a00001c bne cc4 <si5351_write_parameters.isra.1+0xd0>
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c50: e5952008 ldr r2, [r5, #8]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c54: e3a03008 mov r3, #8
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
c58: e595e004 ldr lr, [r5, #4]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c5c: e1a01006 mov r1, r6
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c60: e595c000 ldr ip, [r5]
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c64: e202480f and r4, r2, #983040 ; 0xf0000
c68: e7e3285e ubfx r2, lr, #16, #4
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c6c: e5970000 ldr r0, [r7]
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c70: e1822624 orr r2, r2, r4, lsr #12
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c74: e7e1485c ubfx r4, ip, #16, #2
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c78: e5cd200d strb r2, [sp, #13]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c7c: e08d2003 add r2, sp, r3
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
c80: e5cde00f strb lr, [sp, #15]
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c84: e1884004 orr r4, r8, r4
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
c88: e7e7e45e ubfx lr, lr, #8, #8
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
c8c: e5cdc00c strb ip, [sp, #12]
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
c90: e5cde00e strb lr, [sp, #14]
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
c94: e7e7c45c ubfx ip, ip, #8, #8
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c98: e5cd400a strb r4, [sp, #10]
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
c9c: e5cdc00b strb ip, [sp, #11]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
ca0: ebfffffe bl 0 <regmap_raw_write>
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
}
}
ca4: e28dd010 add sp, sp, #16
ca8: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
}
static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
u8 reg, u8 val)
{
return regmap_write(drvdata->regmap, reg, val);
cac: e5d32000 ldrb r2, [r3]
cb0: e1a01006 mov r1, r6
cb4: e5970000 ldr r0, [r7]
cb8: ebfffffe bl 0 <regmap_write>
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
}
}
cbc: e28dd010 add sp, sp, #16
cc0: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
cc4: e5980000 ldr r0, [r8]
cc8: e3001000 movw r1, #0
ccc: e1a02004 mov r2, r4
cd0: e3401000 movt r1, #0
cd4: e2800020 add r0, r0, #32
cd8: e3a08000 mov r8, #0
cdc: ebfffffe bl 0 <dev_err>
ce0: eaffffda b c50 <si5351_write_parameters.isra.1+0x5c>
00000ce4 <si5351_pll_set_rate>:
return rate;
}
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
ce4: e92d4010 push {r4, lr}
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
ce8: e2803010 add r3, r0, #16
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
cec: e5d02020 ldrb r2, [r0, #32]
return rate;
}
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
cf0: e1a04000 mov r4, r0
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
cf4: e590000c ldr r0, [r0, #12]
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
cf8: e3520000 cmp r2, #0
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
cfc: e2801008 add r1, r0, #8
d00: e2800004 add r0, r0, #4
d04: 13a02022 movne r2, #34 ; 0x22
d08: 03a0201a moveq r2, #26
d0c: ebffffb8 bl bf4 <si5351_write_parameters.isra.1>
/* plla/pllb ctrl is in clk6/clk7 ctrl registers */
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
d10: e5940014 ldr r0, [r4, #20]
d14: e5d41020 ldrb r1, [r4, #32]
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
d18: e3a02040 mov r2, #64 ; 0x40
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
/* plla/pllb ctrl is in clk6/clk7 ctrl registers */
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
d1c: e594300c ldr r3, [r4, #12]
d20: e3500000 cmp r0, #0
d24: e2811016 add r1, r1, #22
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
d28: e5930008 ldr r0, [r3, #8]
d2c: e6ef1071 uxtb r1, r1
d30: 01a03002 moveq r3, r2
d34: 13a03000 movne r3, #0
d38: ebfffffe bl 0 <regmap_update_bits>
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, rate);
return 0;
}
d3c: e3a00000 mov r0, #0
d40: e8bd8010 pop {r4, pc}
00000d44 <si5351_msynth_set_rate>:
return rate;
}
static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
d44: e92d4070 push {r4, r5, r6, lr}
d48: e1a05000 mov r5, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
d4c: e5d03020 ldrb r3, [r0, #32]
return rate;
}
static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
d50: e1a06001 mov r6, r1
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d54: e590000c ldr r0, [r0, #12]
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
d58: e3530005 cmp r3, #5
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d5c: d1a04183 lslle r4, r3, #3
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
d60: c2833054 addgt r3, r3, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d64: d284402a addle r4, r4, #42 ; 0x2a
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d68: e2801008 add r1, r0, #8
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
d6c: c6ef4073 uxtbgt r4, r3
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d70: e2800004 add r0, r0, #4
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d74: d6ef4074 uxtble r4, r4
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d78: e2853010 add r3, r5, #16
d7c: e1a02004 mov r2, r4
d80: ebffff9b bl bf4 <si5351_write_parameters.isra.1>
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
d84: e30d3180 movw r3, #53632 ; 0xd180
d88: e34038f0 movt r3, #2288 ; 0x8f0
d8c: e1560003 cmp r6, r3
d90: 9a000007 bls db4 <si5351_msynth_set_rate+0x70>
divby4 = 1;
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
d94: e5d53020 ldrb r3, [r5, #32]
d98: e3530005 cmp r3, #5
d9c: 8a000019 bhi e08 <si5351_msynth_set_rate+0xc4>
si5351_set_bits(hwdata->drvdata, reg + 2,
da0: e2844002 add r4, r4, #2
da4: e595200c ldr r2, [r5, #12]
da8: e3a0300c mov r3, #12
dac: e6ef1074 uxtb r1, r4
db0: ea000006 b dd0 <si5351_msynth_set_rate+0x8c>
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
db4: e5d53020 ldrb r3, [r5, #32]
db8: e3530005 cmp r3, #5
dbc: 8a000011 bhi e08 <si5351_msynth_set_rate+0xc4>
si5351_set_bits(hwdata->drvdata, reg + 2,
dc0: e2844002 add r4, r4, #2
dc4: e595200c ldr r2, [r5, #12]
dc8: e3a03000 mov r3, #0
dcc: e6ef1074 uxtb r1, r4
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
dd0: e5920008 ldr r0, [r2, #8]
dd4: e3a0200c mov r2, #12
dd8: ebfffffe bl 0 <regmap_update_bits>
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
si5351_set_bits(hwdata->drvdata, reg + 2,
SI5351_OUTPUT_CLK_DIVBY4,
(divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
ddc: e5950014 ldr r0, [r5, #20]
de0: e5d51020 ldrb r1, [r5, #32]
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
de4: e3a02040 mov r2, #64 ; 0x40
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
si5351_set_bits(hwdata->drvdata, reg + 2,
SI5351_OUTPUT_CLK_DIVBY4,
(divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
de8: e595300c ldr r3, [r5, #12]
dec: e3500000 cmp r0, #0
df0: e2811010 add r1, r1, #16
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
df4: e5930008 ldr r0, [r3, #8]
df8: e6ef1071 uxtb r1, r1
dfc: 01a03002 moveq r3, r2
e00: 13a03000 movne r3, #0
e04: ebfffffe bl 0 <regmap_update_bits>
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
divby4, parent_rate, rate);
return 0;
}
e08: e3a00000 mov r0, #0
e0c: e8bd8070 pop {r4, r5, r6, pc}
00000e10 <si5351_regmap_is_writeable>:
}
static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
{
/* reserved registers */
if (reg >= 4 && reg <= 8)
e10: e2413004 sub r3, r1, #4
e14: e3530004 cmp r3, #4
e18: 9a00000c bls e50 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 10 && reg <= 14)
e1c: e241300a sub r3, r1, #10
e20: e3530004 cmp r3, #4
e24: 9a000009 bls e50 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 173 && reg <= 176)
e28: e24130ad sub r3, r1, #173 ; 0xad
e2c: e3530003 cmp r3, #3
e30: 9a000006 bls e50 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 178 && reg <= 182)
return false;
/* read-only */
if (reg == SI5351_DEVICE_STATUS)
e34: e24100b2 sub r0, r1, #178 ; 0xb2
e38: e3510000 cmp r1, #0
e3c: 13500004 cmpne r0, #4
e40: 93a01001 movls r1, #1
e44: 83a01000 movhi r1, #0
e48: e2210001 eor r0, r1, #1
e4c: e12fff1e bx lr
static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
{
/* reserved registers */
if (reg >= 4 && reg <= 8)
return false;
e50: e3a00000 mov r0, #0
return false;
/* read-only */
if (reg == SI5351_DEVICE_STATUS)
return false;
return true;
}
e54: e12fff1e bx lr
00000e58 <_si5351_pll_reparent.isra.4>:
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e58: e3520000 cmp r2, #0
*
* a + b/c = (MSNx_P1 + MSNx_P2/MSNx_P3 + 512)/128
* = (MSNx_P1*MSNx_P3 + MSNx_P2 + 512*MSNx_P3)/(128*MSNx_P3)
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
e5c: e92d4010 push {r4, lr}
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e60: 0a00000f beq ea4 <_si5351_pll_reparent.isra.4+0x4c>
if (parent == SI5351_PLL_SRC_DEFAULT)
e64: e3530000 cmp r3, #0
e68: 0a00000b beq e9c <_si5351_pll_reparent.isra.4+0x44>
return 0;
if (num > 2)
e6c: e3520002 cmp r2, #2
e70: ca000015 bgt ecc <_si5351_pll_reparent.isra.4+0x74>
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
e74: e5900000 ldr r0, [r0]
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e78: e3a02008 mov r2, #8
return 0;
if (num > 2)
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
e7c: e3500004 cmp r0, #4
e80: 0a00000d beq ebc <_si5351_pll_reparent.isra.4+0x64>
e84: e3530001 cmp r3, #1
e88: 1a00000f bne ecc <_si5351_pll_reparent.isra.4+0x74>
e8c: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
e90: e5910000 ldr r0, [r1]
e94: e3a0100f mov r1, #15
e98: ebfffffe bl 0 <regmap_update_bits>
parent != SI5351_PLL_SRC_XTAL)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
(parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
return 0;
e9c: e3a00000 mov r0, #0
ea0: e8bd8010 pop {r4, pc}
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
if (parent == SI5351_PLL_SRC_DEFAULT)
ea4: e3530000 cmp r3, #0
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
ea8: 13a02004 movne r2, #4
if (parent == SI5351_PLL_SRC_DEFAULT)
eac: 0afffffa beq e9c <_si5351_pll_reparent.isra.4+0x44>
return 0;
if (num > 2)
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
eb0: e5900000 ldr r0, [r0]
eb4: e3500004 cmp r0, #4
eb8: 1afffff1 bne e84 <_si5351_pll_reparent.isra.4+0x2c>
parent != SI5351_PLL_SRC_XTAL)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
ebc: e3530001 cmp r3, #1
ec0: 11a03002 movne r3, r2
ec4: 03a03000 moveq r3, #0
ec8: eafffff0 b e90 <_si5351_pll_reparent.isra.4+0x38>
if (parent == SI5351_PLL_SRC_DEFAULT)
return 0;
if (num > 2)
return -EINVAL;
ecc: e3e00015 mvn r0, #21
ed0: e8bd8010 pop {r4, pc}
00000ed4 <si5351_pll_set_parent>:
static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
ed4: e590c00c ldr ip, [r0, #12]
ed8: e59c3000 ldr r3, [ip]
edc: e3530004 cmp r3, #4
ee0: 0a000006 beq f00 <si5351_pll_set_parent+0x2c>
ee4: e3510000 cmp r1, #0
return -EPERM;
if (index > 1)
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
ee8: 05d02020 ldrbeq r2, [r0, #32]
eec: 03a03001 moveq r3, #1
static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
ef0: 1a00000d bne f2c <si5351_pll_set_parent+0x58>
return -EPERM;
if (index > 1)
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
ef4: e28c1008 add r1, ip, #8
ef8: e1a0000c mov r0, ip
efc: eaffffd5 b e58 <_si5351_pll_reparent.isra.4>
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
if (index > 1)
f00: e3510001 cmp r1, #1
f04: 8a000006 bhi f24 <si5351_pll_set_parent+0x50>
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
f08: e3510000 cmp r1, #0
f0c: e5d02020 ldrb r2, [r0, #32]
f10: e28c1008 add r1, ip, #8
f14: e1a0000c mov r0, ip
f18: 03a03001 moveq r3, #1
f1c: 13a03002 movne r3, #2
f20: eaffffcc b e58 <_si5351_pll_reparent.isra.4>
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
if (index > 1)
return -EINVAL;
f24: e3e00015 mvn r0, #21
f28: e12fff1e bx lr
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
f2c: e3e00000 mvn r0, #0
f30: e12fff1e bx lr
00000f34 <_si5351_clkout_reparent.isra.7>:
static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
f34: e3520008 cmp r2, #8
};
/*
* Si5351 clkout divider
*/
static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
f38: e92d4010 push {r4, lr}
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
f3c: ca000016 bgt f9c <_si5351_clkout_reparent.isra.7+0x68>
return -EINVAL;
switch (parent) {
f40: e2433001 sub r3, r3, #1
f44: e3530003 cmp r3, #3
f48: 979ff103 ldrls pc, [pc, r3, lsl #2]
f4c: ea000016 b fac <_si5351_clkout_reparent.isra.7+0x78>
f50: 00000fa4 .word 0x00000fa4
f54: 00000f80 .word 0x00000f80
f58: 00000f60 .word 0x00000f60
f5c: 00000f90 .word 0x00000f90
f60: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
f64: e282c010 add ip, r2, #16
f68: e5910000 ldr r0, [r1]
f6c: e3a0200c mov r2, #12
f70: e6ef107c uxtb r1, ip
f74: ebfffffe bl 0 <regmap_update_bits>
return 0;
}
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
SI5351_CLK_INPUT_MASK, val);
return 0;
f78: e3a00000 mov r0, #0
f7c: e8bd8010 pop {r4, pc}
case SI5351_CLKOUT_SRC_MSYNTH_N:
val = SI5351_CLK_INPUT_MULTISYNTH_N;
break;
case SI5351_CLKOUT_SRC_MSYNTH_0_4:
/* clk0/clk4 can only connect to its own multisync */
if (num == 0 || num == 4)
f80: e3d23004 bics r3, r2, #4
f84: 03a0300c moveq r3, #12
f88: 13a03008 movne r3, #8
f8c: eafffff4 b f64 <_si5351_clkout_reparent.isra.7+0x30>
break;
case SI5351_CLKOUT_SRC_XTAL:
val = SI5351_CLK_INPUT_XTAL;
break;
case SI5351_CLKOUT_SRC_CLKIN:
if (drvdata->variant != SI5351_VARIANT_C)
f90: e5903000 ldr r3, [r0]
f94: e3530004 cmp r3, #4
f98: 0afffff1 beq f64 <_si5351_clkout_reparent.isra.7+0x30>
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
return -EINVAL;
f9c: e3e00015 mvn r0, #21
}
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
SI5351_CLK_INPUT_MASK, val);
return 0;
}
fa0: e8bd8010 pop {r4, pc}
u8 val;
if (num > 8)
return -EINVAL;
switch (parent) {
fa4: e3a0300c mov r3, #12
fa8: eaffffed b f64 <_si5351_clkout_reparent.isra.7+0x30>
return -EINVAL;
val = SI5351_CLK_INPUT_CLKIN;
break;
default:
return 0;
fac: e3a00000 mov r0, #0
fb0: e8bd8010 pop {r4, pc}
00000fb4 <si5351_clkout_set_parent>:
return index;
}
static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
{
fb4: e3510003 cmp r1, #3
fb8: e1a02000 mov r2, r0
case 3:
parent = SI5351_CLKOUT_SRC_CLKIN;
break;
}
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
fbc: e590000c ldr r0, [r0, #12]
fc0: 93003000 movwls r3, #0
return index;
}
static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
{
fc4: 83a03000 movhi r3, #0
fc8: 93403000 movtls r3, #0
fcc: 90833101 addls r3, r3, r1, lsl #2
case 3:
parent = SI5351_CLKOUT_SRC_CLKIN;
break;
}
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
fd0: e5d22020 ldrb r2, [r2, #32]
fd4: e2801008 add r1, r0, #8
fd8: 95933024 ldrls r3, [r3, #36] ; 0x24
fdc: eaffffd4 b f34 <_si5351_clkout_reparent.isra.7>
00000fe0 <si5351_i2c_probe>:
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
fe0: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
{
struct device_node *child, *np = client->dev.of_node;
struct si5351_platform_data *pdata;
struct property *prop;
const __be32 *p;
int num = 0;
fe4: e3a06000 mov r6, #0
MODULE_DEVICE_TABLE(of, si5351_dt_ids);
static int si5351_dt_parse(struct i2c_client *client,
enum si5351_variant variant)
{
struct device_node *child, *np = client->dev.of_node;
fe8: e5905204 ldr r5, [r0, #516] ; 0x204
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
fec: e24dd04c sub sp, sp, #76 ; 0x4c
enum si5351_variant variant = (enum si5351_variant)id->driver_data;
ff0: e5917014 ldr r7, [r1, #20]
struct property *prop;
const __be32 *p;
int num = 0;
u32 val;
if (np == NULL)
ff4: e1550006 cmp r5, r6
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
ff8: e58d0004 str r0, [sp, #4]
{
struct device_node *child, *np = client->dev.of_node;
struct si5351_platform_data *pdata;
struct property *prop;
const __be32 *p;
int num = 0;
ffc: e58d6024 str r6, [sp, #36] ; 0x24
u32 val;
if (np == NULL)
1000: 0a000041 beq 110c <si5351_i2c_probe+0x12c>
return 0;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1004: e280b020 add fp, r0, #32
va_list ap);
extern __printf(3, 4)
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
1008: e30820d0 movw r2, #32976 ; 0x80d0
100c: e3a010c8 mov r1, #200 ; 0xc8
1010: e1a0000b mov r0, fp
1014: ebfffffe bl 0 <devm_kmalloc>
if (!pdata)
1018: e2508000 subs r8, r0, #0
101c: 0a000341 beq 1d28 <si5351_i2c_probe+0xd48>
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
1020: e28d3024 add r3, sp, #36 ; 0x24
1024: e3001000 movw r1, #0
1028: e3401000 movt r1, #0
102c: e1a02006 mov r2, r6
1030: e1a00005 mov r0, r5
1034: e1a09003 mov r9, r3
1038: e58d3000 str r3, [sp]
103c: ebfffffe bl 0 <of_find_property>
1040: e1a01006 mov r1, r6
1044: e1a02009 mov r2, r9
1048: e1a04000 mov r4, r0
104c: ebfffffe bl 0 <of_prop_next_u32>
1050: e2501000 subs r1, r0, #0
1054: 0a000232 beq 1924 <si5351_i2c_probe+0x944>
if (num >= 2) {
1058: e59d2024 ldr r2, [sp, #36] ; 0x24
105c: e3520001 cmp r2, #1
1060: d28d6034 addle r6, sp, #52 ; 0x34
return -EINVAL;
}
switch (val) {
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
1064: d3a09001 movle r9, #1
dev_err(&client->dev,
"invalid parent %d for pll %d\n",
val, num);
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
1068: d3a0a002 movle sl, #2
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
if (num >= 2) {
106c: ca000015 bgt 10c8 <si5351_i2c_probe+0xe8>
dev_err(&client->dev,
"invalid pll %d on pll-source prop\n", num);
return -EINVAL;
}
p = of_prop_next_u32(prop, p, &val);
1070: e1a02006 mov r2, r6
1074: e1a00004 mov r0, r4
1078: ebfffffe bl 0 <of_prop_next_u32>
if (!p) {
107c: e2501000 subs r1, r0, #0
1080: 0a0002df beq 1c04 <si5351_i2c_probe+0xc24>
dev_err(&client->dev,
"missing pll-source for pll %d\n", num);
return -EINVAL;
}
switch (val) {
1084: e59d2034 ldr r2, [sp, #52] ; 0x34
1088: e3520000 cmp r2, #0
108c: 0a00001b beq 1100 <si5351_i2c_probe+0x120>
1090: e3520001 cmp r2, #1
1094: 1a000011 bne 10e0 <si5351_i2c_probe+0x100>
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
break;
case 1:
if (variant != SI5351_VARIANT_C) {
1098: e3570004 cmp r7, #4
109c: 1a00000f bne 10e0 <si5351_i2c_probe+0x100>
dev_err(&client->dev,
"invalid parent %d for pll %d\n",
val, num);
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
10a0: e59d3024 ldr r3, [sp, #36] ; 0x24
10a4: e788a103 str sl, [r8, r3, lsl #2]
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
10a8: e59d2000 ldr r2, [sp]
10ac: e1a00004 mov r0, r4
10b0: ebfffffe bl 0 <of_prop_next_u32>
10b4: e2501000 subs r1, r0, #0
10b8: 0a000219 beq 1924 <si5351_i2c_probe+0x944>
if (num >= 2) {
10bc: e59d2024 ldr r2, [sp, #36] ; 0x24
10c0: e3520001 cmp r2, #1
10c4: daffffe9 ble 1070 <si5351_i2c_probe+0x90>
dev_err(&client->dev,
10c8: e3001000 movw r1, #0
10cc: e1a0000b mov r0, fp
10d0: e3401000 movt r1, #0
10d4: ebfffffe bl 0 <dev_err>
"invalid pll %d on pll-source prop\n", num);
return -EINVAL;
10d8: e3e00015 mvn r0, #21
10dc: ea000005 b 10f8 <si5351_i2c_probe+0x118>
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
break;
default:
dev_err(&client->dev,
10e0: e3001000 movw r1, #0
10e4: e1a0000b mov r0, fp
10e8: e3401000 movt r1, #0
10ec: e59d3024 ldr r3, [sp, #36] ; 0x24
10f0: ebfffffe bl 0 <dev_err>
"invalid parent %d for pll %d\n", val, num);
return -EINVAL;
10f4: e3e00015 mvn r0, #21
if (!IS_ERR(drvdata->pxtal))
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_disable_unprepare(drvdata->pclkin);
return ret;
}
10f8: e28dd04c add sp, sp, #76 ; 0x4c
10fc: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
return -EINVAL;
}
switch (val) {
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
1100: e59d3024 ldr r3, [sp, #36] ; 0x24
1104: e7889103 str r9, [r8, r3, lsl #2]
1108: eaffffe6 b 10a8 <si5351_i2c_probe+0xc8>
110c: e59d3004 ldr r3, [sp, #4]
1110: e59380a0 ldr r8, [r3, #160] ; 0xa0
ret = si5351_dt_parse(client, variant);
if (ret)
return ret;
pdata = client->dev.platform_data;
if (!pdata)
1114: e3580000 cmp r8, #0
1118: 0a000304 beq 1d30 <si5351_i2c_probe+0xd50>
111c: e283b020 add fp, r3, #32
1120: e30820d0 movw r2, #32976 ; 0x80d0
1124: e3a0108c mov r1, #140 ; 0x8c
1128: e1a0000b mov r0, fp
112c: ebfffffe bl 0 <devm_kmalloc>
return -EINVAL;
drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
if (drvdata == NULL) {
1130: e2504000 subs r4, r0, #0
1134: 0a00030d beq 1d70 <si5351_i2c_probe+0xd90>
return dev->driver_data;
}
static inline void dev_set_drvdata(struct device *dev, void *data)
{
dev->driver_data = data;
1138: e59d3004 ldr r3, [sp, #4]
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
113c: e3001000 movw r1, #0
1140: e3401000 movt r1, #0
1144: e1a0000b mov r0, fp
1148: e58340a4 str r4, [r3, #164] ; 0xa4
dev_err(&client->dev, "unable to allocate driver data\n");
return -ENOMEM;
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
114c: e5843004 str r3, [r4, #4]
drvdata->variant = variant;
1150: e5847000 str r7, [r4]
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1154: ebfffffe bl 0 <devm_clk_get>
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
1158: e3001000 movw r1, #0
115c: e3401000 movt r1, #0
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1160: e5840014 str r0, [r4, #20]
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
1164: e1a0000b mov r0, fp
1168: ebfffffe bl 0 <devm_clk_get>
if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
116c: e5945014 ldr r5, [r4, #20]
1170: e3e03f81 mvn r3, #516 ; 0x204
1174: e1550003 cmp r5, r3
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
1178: e5840028 str r0, [r4, #40] ; 0x28
if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
117c: 0a0001d6 beq 18dc <si5351_i2c_probe+0x8fc>
1180: e1500003 cmp r0, r3
1184: 0affffdb beq 10f8 <si5351_i2c_probe+0x118>
/*
* Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
* VARIANT_C can have CLKIN instead.
*/
if (IS_ERR(drvdata->pxtal) &&
1188: e3750a01 cmn r5, #4096 ; 0x1000
118c: 8a0001b9 bhi 1878 <si5351_i2c_probe+0x898>
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
dev_err(&client->dev, "missing parent clock\n");
return -EINVAL;
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
1190: e59f1c60 ldr r1, [pc, #3168] ; 1df8 <si5351_i2c_probe+0xe18>
1194: e59d0004 ldr r0, [sp, #4]
1198: ebfffffe bl 0 <devm_regmap_init_i2c>
if (IS_ERR(drvdata->regmap)) {
119c: e3700a01 cmn r0, #4096 ; 0x1000
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
dev_err(&client->dev, "missing parent clock\n");
return -EINVAL;
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
11a0: e5840008 str r0, [r4, #8]
if (IS_ERR(drvdata->regmap)) {
11a4: 8a0001be bhi 18a4 <si5351_i2c_probe+0x8c4>
}
static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
u8 reg, u8 val)
{
return regmap_write(drvdata->regmap, reg, val);
11a8: e3a020f0 mov r2, #240 ; 0xf0
11ac: e3a01002 mov r1, #2
11b0: ebfffffe bl 0 <regmap_write>
}
/* Disable interrupts */
si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
/* Ensure pll select is on XTAL for Si5351A/B */
if (drvdata->variant != SI5351_VARIANT_C)
11b4: e5943000 ldr r3, [r4]
11b8: e3530004 cmp r3, #4
11bc: 0a000004 beq 11d4 <si5351_i2c_probe+0x1f4>
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
11c0: e3a03000 mov r3, #0
11c4: e3a0200c mov r2, #12
11c8: e3a0100f mov r1, #15
11cc: e5940008 ldr r0, [r4, #8]
11d0: ebfffffe bl 0 <regmap_update_bits>
11d4: e284a008 add sl, r4, #8
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
11d8: e5983000 ldr r3, [r8]
11dc: e3a02000 mov r2, #0
11e0: e1a00004 mov r0, r4
11e4: e1a0100a mov r1, sl
11e8: ebffff1a bl e58 <_si5351_pll_reparent.isra.4>
if (ret) {
11ec: e2507000 subs r7, r0, #0
11f0: 1a0001b1 bne 18bc <si5351_i2c_probe+0x8dc>
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
11f4: e3a02001 mov r2, #1
11f8: e5983004 ldr r3, [r8, #4]
11fc: e1a0100a mov r1, sl
1200: e1a00004 mov r0, r4
1204: ebffff13 bl e58 <_si5351_pll_reparent.isra.4>
if (ret) {
1208: e2507000 subs r7, r0, #0
if (drvdata->variant != SI5351_VARIANT_C)
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
120c: 13a02001 movne r2, #1
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
if (ret) {
1210: 1a0001aa bne 18c0 <si5351_i2c_probe+0x8e0>
1214: e1a06008 mov r6, r8
1218: e3a09010 mov r9, #16
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
121c: e3a05003 mov r5, #3
1220: e58d8014 str r8, [sp, #20]
return ret;
}
}
for (n = 0; n < 8; n++) {
ret = _si5351_msynth_reparent(drvdata, n,
1224: e5963008 ldr r3, [r6, #8]
* MSx_P1 = 0, MSx_P2 = 0, MSx_P3 = 1, MSx_INT = 1, MSx_DIVBY4 = 11b
*/
static int _si5351_msynth_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
1228: e3530000 cmp r3, #0
122c: 0a000006 beq 124c <si5351_i2c_probe+0x26c>
return 0;
if (num > 8)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1230: e3530001 cmp r3, #1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1234: e3a02020 mov r2, #32
1238: e1a01009 mov r1, r9
123c: e5940008 ldr r0, [r4, #8]
1240: 11a03002 movne r3, r2
1244: 03a03000 moveq r3, #0
1248: ebfffffe bl 0 <regmap_update_bits>
"failed to reparent multisynth %d to %d\n",
n, pdata->clkout[n].multisynth_src);
return ret;
}
ret = _si5351_clkout_reparent(drvdata, n,
124c: e596300c ldr r3, [r6, #12]
1250: e1a02007 mov r2, r7
1254: e1a0100a mov r1, sl
1258: e1a00004 mov r0, r4
125c: ebffff34 bl f34 <_si5351_clkout_reparent.isra.7>
pdata->clkout[n].clkout_src);
if (ret) {
1260: e3500000 cmp r0, #0
1264: 1a00019e bne 18e4 <si5351_i2c_probe+0x904>
u8 mask;
if (num > 8)
return -EINVAL;
switch (drive) {
1268: e5963010 ldr r3, [r6, #16]
126c: e2433002 sub r3, r3, #2
1270: e3530006 cmp r3, #6
1274: 979ff103 ldrls pc, [pc, r3, lsl #2]
1278: ea00000b b 12ac <si5351_i2c_probe+0x2cc>
127c: 00001674 .word 0x00001674
1280: 000012ac .word 0x000012ac
1284: 00001298 .word 0x00001298
1288: 000012ac .word 0x000012ac
128c: 00001684 .word 0x00001684
1290: 000012ac .word 0x000012ac
1294: 0000167c .word 0x0000167c
1298: e3a03001 mov r3, #1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
129c: e3a02003 mov r2, #3
12a0: e1a01009 mov r1, r9
12a4: e5940008 ldr r0, [r4, #8]
12a8: ebfffffe bl 0 <regmap_update_bits>
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
12ac: e3570003 cmp r7, #3
"failed set drive strength of clkout%d to %d\n",
n, pdata->clkout[n].drive);
return ret;
}
ret = _si5351_clkout_set_disable_state(drvdata, n,
12b0: e5962014 ldr r2, [r6, #20]
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
12b4: ca0000f4 bgt 168c <si5351_i2c_probe+0x6ac>
12b8: e1a03087 lsl r3, r7, #1
12bc: e3a01018 mov r1, #24
12c0: e6ef3073 uxtb r3, r3
u8 val;
if (num > 8)
return -EINVAL;
switch (state) {
12c4: e2420001 sub r0, r2, #1
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
SI5351_CLK7_4_DISABLE_STATE;
u8 shift = (num < 4) ? (2 * num) : (2 * (num-4));
u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift;
12c8: e1a02315 lsl r2, r5, r3
u8 val;
if (num > 8)
return -EINVAL;
switch (state) {
12cc: e3500003 cmp r0, #3
12d0: 979ff100 ldrls pc, [pc, r0, lsl #2]
12d4: ea000006 b 12f4 <si5351_i2c_probe+0x314>
12d8: 000012e8 .word 0x000012e8
12dc: 00001668 .word 0x00001668
12e0: 0000165c .word 0x0000165c
12e4: 00001654 .word 0x00001654
12e8: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
12ec: e5940008 ldr r0, [r4, #8]
12f0: ebfffffe bl 0 <regmap_update_bits>
n, pdata->pll_src[n]);
return ret;
}
}
for (n = 0; n < 8; n++) {
12f4: e2877001 add r7, r7, #1
12f8: e2866018 add r6, r6, #24
12fc: e3570008 cmp r7, #8
1300: e2899001 add r9, r9, #1
1304: 1affffc6 bne 1224 <si5351_i2c_probe+0x244>
n, pdata->clkout[n].disable_state);
return ret;
}
}
if (!IS_ERR(drvdata->pxtal))
1308: e5945014 ldr r5, [r4, #20]
130c: e3750a01 cmn r5, #4096 ; 0x1000
1310: 8a000003 bhi 1324 <si5351_i2c_probe+0x344>
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{
int ret;
ret = clk_prepare(clk);
1314: e1a00005 mov r0, r5
1318: ebfffffe bl 0 <clk_prepare>
if (ret)
131c: e3500000 cmp r0, #0
1320: 0a0000e5 beq 16bc <si5351_i2c_probe+0x6dc>
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
1324: e5945028 ldr r5, [r4, #40] ; 0x28
1328: e3750a01 cmn r5, #4096 ; 0x1000
132c: 8a000003 bhi 1340 <si5351_i2c_probe+0x360>
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{
int ret;
ret = clk_prepare(clk);
1330: e1a00005 mov r0, r5
1334: ebfffffe bl 0 <clk_prepare>
if (ret)
1338: e3500000 cmp r0, #0
133c: 0a0000d7 beq 16a0 <si5351_i2c_probe+0x6c0>
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
1340: e28d6034 add r6, sp, #52 ; 0x34
init.name = si5351_input_names[0];
1344: e3003000 movw r3, #0
1348: e3403000 movt r3, #0
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
134c: e3a01014 mov r1, #20
1350: e1a00006 mov r0, r6
init.name = si5351_input_names[0];
1354: e1a05003 mov r5, r3
1358: e58d300c str r3, [sp, #12]
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
135c: ebfffffe bl 0 <__memzero>
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
1360: e59f3a94 ldr r3, [pc, #2708] ; 1dfc <si5351_i2c_probe+0xe1c>
init.flags = 0;
1364: e3a02000 mov r2, #0
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
1368: e58d5034 str r5, [sp, #52] ; 0x34
init.ops = &si5351_xtal_ops;
init.flags = 0;
136c: e58d2044 str r2, [sp, #68] ; 0x44
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
1370: e58d3038 str r3, [sp, #56] ; 0x38
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
1374: e5940014 ldr r0, [r4, #20]
1378: e3700a01 cmn r0, #4096 ; 0x1000
137c: 8a000005 bhi 1398 <si5351_i2c_probe+0x3b8>
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
1380: ebfffffe bl 0 <__clk_get_name>
1384: e1a03004 mov r3, r4
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
1388: e3a02001 mov r2, #1
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
138c: e5a30018 str r0, [r3, #24]!
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
1390: e5cd2040 strb r2, [sp, #64] ; 0x40
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
init.parent_names = &drvdata->pxtal_name;
1394: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = 1;
}
drvdata->xtal.init = &init;
1398: e5846024 str r6, [r4, #36] ; 0x24
clk = devm_clk_register(&client->dev, &drvdata->xtal);
139c: e284101c add r1, r4, #28
13a0: e1a0000b mov r0, fp
13a4: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
13a8: e3700a01 cmn r0, #4096 ; 0x1000
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
}
drvdata->xtal.init = &init;
clk = devm_clk_register(&client->dev, &drvdata->xtal);
13ac: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
13b0: 8a000091 bhi 15fc <si5351_i2c_probe+0x61c>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
13b4: e5943000 ldr r3, [r4]
13b8: e3530004 cmp r3, #4
13bc: 0a000217 beq 1c20 <si5351_i2c_probe+0xc40>
13c0: e3003000 movw r3, #0
13c4: e3403000 movt r3, #0
13c8: e58d3010 str r3, [sp, #16]
goto err_clk;
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
13cc: e3a05001 mov r5, #1
parent_names[0] = si5351_input_names[0];
13d0: e59d300c ldr r3, [sp, #12]
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
13d4: e3a09000 mov r9, #0
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
13d8: e3a01014 mov r1, #20
13dc: e1a00006 mov r0, r6
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
13e0: e59faa18 ldr sl, [pc, #2584] ; 1e00 <si5351_i2c_probe+0xe20>
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
13e4: e3007000 movw r7, #0
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
13e8: e58d3024 str r3, [sp, #36] ; 0x24
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
13ec: e3407000 movt r7, #0
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
13f0: e59d3010 ldr r3, [sp, #16]
13f4: e58d3028 str r3, [sp, #40] ; 0x28
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
13f8: e28d3024 add r3, sp, #36 ; 0x24
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
13fc: e5844048 str r4, [r4, #72] ; 0x48
drvdata->pll[0].hw.init = &init;
1400: e5846044 str r6, [r4, #68] ; 0x44
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
1404: e5c4905c strb r9, [r4, #92] ; 0x5c
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
1408: e58d3000 str r3, [sp]
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
140c: ebfffffe bl 0 <__memzero>
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1410: e284103c add r1, r4, #60 ; 0x3c
1414: e1a0000b mov r0, fp
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
1418: e59d3000 ldr r3, [sp]
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
141c: e58d9044 str r9, [sp, #68] ; 0x44
init.parent_names = parent_names;
init.num_parents = num_parents;
1420: e5cd5040 strb r5, [sp, #64] ; 0x40
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
1424: e58d303c str r3, [sp, #60] ; 0x3c
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
1428: e58d7034 str r7, [sp, #52] ; 0x34
init.ops = &si5351_pll_ops;
142c: e58da038 str sl, [sp, #56] ; 0x38
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1430: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1434: e3700a01 cmn r0, #4096 ; 0x1000
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1438: e1a03000 mov r3, r0
if (IS_ERR(clk)) {
143c: 8a000215 bhi 1c98 <si5351_i2c_probe+0xcb8>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
1440: e3a03001 mov r3, #1
drvdata->pll[1].drvdata = drvdata;
1444: e584406c str r4, [r4, #108] ; 0x6c
ret = PTR_ERR(clk);
goto err_clk;
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
1448: e5c43080 strb r3, [r4, #128] ; 0x80
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
144c: e3a01014 mov r1, #20
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
1450: e5846068 str r6, [r4, #104] ; 0x68
memset(&init, 0, sizeof(init));
1454: e1a00006 mov r0, r6
1458: ebfffffe bl 0 <__memzero>
if (drvdata->variant == SI5351_VARIANT_B) {
145c: e5943000 ldr r3, [r4]
1460: e3530003 cmp r3, #3
1464: 0a00009b beq 16d8 <si5351_i2c_probe+0x6f8>
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
1468: e59d2000 ldr r2, [sp]
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
146c: e3003000 movw r3, #0
1470: e3403000 movt r3, #0
init.ops = &si5351_pll_ops;
1474: e58da038 str sl, [sp, #56] ; 0x38
init.flags = 0;
1478: e58d9044 str r9, [sp, #68] ; 0x44
init.parent_names = parent_names;
147c: e58d203c str r2, [sp, #60] ; 0x3c
init.num_parents = num_parents;
1480: e5cd5040 strb r5, [sp, #64] ; 0x40
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
1484: e58d3034 str r3, [sp, #52] ; 0x34
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
}
clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
1488: e2841060 add r1, r4, #96 ; 0x60
148c: e1a0000b mov r0, fp
1490: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1494: e3700a01 cmn r0, #4096 ; 0x1000
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
}
clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
1498: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
149c: 8a000056 bhi 15fc <si5351_i2c_probe+0x61c>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14a0: e5943000 ldr r3, [r4]
va_list ap);
extern __printf(3, 4)
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
14a4: e30820d0 movw r2, #32976 ; 0x80d0
parent_names[0] = si5351_pll_names[0];
14a8: e58d7024 str r7, [sp, #36] ; 0x24
14ac: e1a0000b mov r0, fp
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14b0: e3530002 cmp r3, #2
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
14b4: e5943000 ldr r3, [r4]
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14b8: 03a05003 moveq r5, #3
14bc: 03a0906c moveq r9, #108 ; 0x6c
14c0: 13a05008 movne r5, #8
14c4: 13a09e12 movne r9, #288 ; 0x120
14c8: 03a0a00c moveq sl, #12
14cc: 058d5008 streq r5, [sp, #8]
14d0: 13a0a020 movne sl, #32
14d4: 158d5008 strne r5, [sp, #8]
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
14d8: e3530003 cmp r3, #3
14dc: e1a01009 mov r1, r9
parent_names[1] = si5351_pll_names[2];
14e0: 03003000 movweq r3, #0
else
parent_names[1] = si5351_pll_names[1];
14e4: 13003000 movwne r3, #0
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
parent_names[1] = si5351_pll_names[2];
14e8: 03403000 movteq r3, #0
else
parent_names[1] = si5351_pll_names[1];
14ec: 13403000 movtne r3, #0
14f0: e58d3028 str r3, [sp, #40] ; 0x28
14f4: ebfffffe bl 0 <devm_kmalloc>
14f8: e1a01009 mov r1, r9
14fc: e30820d0 movw r2, #32976 ; 0x80d0
drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
1500: e5840084 str r0, [r4, #132] ; 0x84
1504: e1a0000b mov r0, fp
1508: ebfffffe bl 0 <devm_kmalloc>
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->clkout), GFP_KERNEL);
drvdata->onecell.clk_num = num_clocks;
150c: e5845010 str r5, [r4, #16]
1510: e1a0100a mov r1, sl
1514: e30820d0 movw r2, #32976 ; 0x80d0
else
parent_names[1] = si5351_pll_names[1];
drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
1518: e5840088 str r0, [r4, #136] ; 0x88
151c: e1a0000b mov r0, fp
1520: ebfffffe bl 0 <devm_kmalloc>
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1524: e5943084 ldr r3, [r4, #132] ; 0x84
1528: e3530000 cmp r3, #0
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->clkout), GFP_KERNEL);
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
152c: e584000c str r0, [r4, #12]
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1530: 0a000072 beq 1700 <si5351_i2c_probe+0x720>
1534: e5942088 ldr r2, [r4, #136] ; 0x88
1538: e3500000 cmp r0, #0
153c: 13520000 cmpne r2, #0
1540: 03a09001 moveq r9, #1
1544: 13a09000 movne r9, #0
1548: 0a00006c beq 1700 <si5351_i2c_probe+0x720>
!drvdata->onecell.clks)) {
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
154c: e3005000 movw r5, #0
1550: e59fa8ac ldr sl, [pc, #2220] ; 1e04 <si5351_i2c_probe+0xe24>
1554: e3405000 movt r5, #0
1558: ea000004 b 1570 <si5351_i2c_probe+0x590>
155c: e59d3008 ldr r3, [sp, #8]
1560: e1590003 cmp r9, r3
1564: 0a00006b beq 1718 <si5351_i2c_probe+0x738>
1568: e5943084 ldr r3, [r4, #132] ; 0x84
156c: e5ba5004 ldr r5, [sl, #4]!
1570: e1a07289 lsl r7, r9, #5
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
1574: e3a01014 mov r1, #20
1578: e0877109 add r7, r7, r9, lsl #2
157c: e1a00006 mov r0, r6
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
drvdata->msynth[n].num = n;
1580: e0833007 add r3, r3, r7
1584: e2888018 add r8, r8, #24
1588: e5c39020 strb r9, [r3, #32]
!drvdata->onecell.clks)) {
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
158c: e2899001 add r9, r9, #1
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
1590: e5943084 ldr r3, [r4, #132] ; 0x84
1594: e0833007 add r3, r3, r7
1598: e583400c str r4, [r3, #12]
drvdata->msynth[n].hw.init = &init;
159c: e5943084 ldr r3, [r4, #132] ; 0x84
15a0: e0833007 add r3, r3, r7
15a4: e5836008 str r6, [r3, #8]
memset(&init, 0, sizeof(init));
15a8: ebfffffe bl 0 <__memzero>
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
15ac: e59f2854 ldr r2, [pc, #2132] ; 1e08 <si5351_i2c_probe+0xe28>
init.flags = 0;
if (pdata->clkout[n].pll_master)
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = 2;
15b0: e3a03002 mov r3, #2
clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
15b4: e1a0000b mov r0, fp
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
15b8: e58d2038 str r2, [sp, #56] ; 0x38
init.flags = 0;
15bc: e3a02000 mov r2, #0
for (n = 0; n < num_clocks; n++) {
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
15c0: e58d5034 str r5, [sp, #52] ; 0x34
init.ops = &si5351_msynth_ops;
init.flags = 0;
15c4: e58d2044 str r2, [sp, #68] ; 0x44
if (pdata->clkout[n].pll_master)
15c8: e5d81000 ldrb r1, [r8]
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = 2;
15cc: e5cd3040 strb r3, [sp, #64] ; 0x40
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
init.flags = 0;
if (pdata->clkout[n].pll_master)
15d0: e1510002 cmp r1, r2
init.flags |= CLK_SET_RATE_PARENT;
15d4: 13a02004 movne r2, #4
15d8: 158d2044 strne r2, [sp, #68] ; 0x44
init.parent_names = parent_names;
15dc: e59d2000 ldr r2, [sp]
15e0: e58d203c str r2, [sp, #60] ; 0x3c
init.num_parents = 2;
clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
15e4: e5941084 ldr r1, [r4, #132] ; 0x84
15e8: e0811007 add r1, r1, r7
15ec: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
15f0: e3700a01 cmn r0, #4096 ; 0x1000
15f4: 9affffd8 bls 155c <si5351_i2c_probe+0x57c>
15f8: e1a05000 mov r5, r0
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
if (IS_ERR(clk)) {
dev_err(&client->dev, "unable to register %s\n",
15fc: e3001000 movw r1, #0
1600: e1a0000b mov r0, fp
1604: e3401000 movt r1, #0
1608: e59d2034 ldr r2, [sp, #52] ; 0x34
160c: ebfffffe bl 0 <dev_err>
}
return 0;
err_clk:
if (!IS_ERR(drvdata->pxtal))
1610: e5946014 ldr r6, [r4, #20]
1614: e3760a01 cmn r6, #4096 ; 0x1000
1618: 8a000003 bhi 162c <si5351_i2c_probe+0x64c>
}
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
static inline void clk_disable_unprepare(struct clk *clk)
{
clk_disable(clk);
161c: e1a00006 mov r0, r6
1620: ebfffffe bl 0 <clk_disable>
clk_unprepare(clk);
1624: e1a00006 mov r0, r6
1628: ebfffffe bl 0 <clk_unprepare>
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
162c: e5944028 ldr r4, [r4, #40] ; 0x28
1630: e3740a01 cmn r4, #4096 ; 0x1000
1634: 8a0000a8 bhi 18dc <si5351_i2c_probe+0x8fc>
}
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
static inline void clk_disable_unprepare(struct clk *clk)
{
clk_disable(clk);
1638: e1a00004 mov r0, r4
163c: ebfffffe bl 0 <clk_disable>
clk_unprepare(clk);
1640: e1a00004 mov r0, r4
1644: ebfffffe bl 0 <clk_unprepare>
clk_disable_unprepare(drvdata->pclkin);
return ret;
1648: e1a00005 mov r0, r5
}
164c: e28dd04c add sp, sp, #76 ; 0x4c
1650: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
1654: e1a03002 mov r3, r2
1658: eaffff23 b 12ec <si5351_i2c_probe+0x30c>
165c: e3a00002 mov r0, #2
1660: e1a03310 lsl r3, r0, r3
1664: eaffff20 b 12ec <si5351_i2c_probe+0x30c>
1668: e3a00001 mov r0, #1
166c: e1a03310 lsl r3, r0, r3
1670: eaffff1d b 12ec <si5351_i2c_probe+0x30c>
u8 mask;
if (num > 8)
return -EINVAL;
switch (drive) {
1674: e3a03000 mov r3, #0
1678: eaffff07 b 129c <si5351_i2c_probe+0x2bc>
167c: e3a03003 mov r3, #3
1680: eaffff05 b 129c <si5351_i2c_probe+0x2bc>
1684: e3a03002 mov r3, #2
1688: eaffff03 b 129c <si5351_i2c_probe+0x2bc>
168c: e287307c add r3, r7, #124 ; 0x7c
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
1690: e3a01019 mov r1, #25
1694: e1a03083 lsl r3, r3, #1
1698: e6ef3073 uxtb r3, r3
169c: eaffff08 b 12c4 <si5351_i2c_probe+0x2e4>
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
16a0: e1a00005 mov r0, r5
16a4: ebfffffe bl 0 <clk_enable>
if (ret)
16a8: e3500000 cmp r0, #0
16ac: 0affff23 beq 1340 <si5351_i2c_probe+0x360>
clk_unprepare(clk);
16b0: e1a00005 mov r0, r5
16b4: ebfffffe bl 0 <clk_unprepare>
16b8: eaffff20 b 1340 <si5351_i2c_probe+0x360>
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
16bc: e1a00005 mov r0, r5
16c0: ebfffffe bl 0 <clk_enable>
if (ret)
16c4: e3500000 cmp r0, #0
16c8: 0affff15 beq 1324 <si5351_i2c_probe+0x344>
clk_unprepare(clk);
16cc: e1a00005 mov r0, r5
16d0: ebfffffe bl 0 <clk_unprepare>
16d4: eaffff12 b 1324 <si5351_i2c_probe+0x344>
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
16d8: e3003000 movw r3, #0
init.ops = &si5351_vxco_ops;
16dc: e28aa050 add sl, sl, #80 ; 0x50
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
16e0: e3403000 movt r3, #0
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
16e4: e3a02010 mov r2, #16
init.parent_names = NULL;
16e8: e58d903c str r9, [sp, #60] ; 0x3c
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
init.ops = &si5351_vxco_ops;
16ec: e58da038 str sl, [sp, #56] ; 0x38
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
16f0: e5cd9040 strb r9, [sp, #64] ; 0x40
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
16f4: e58d3034 str r3, [sp, #52] ; 0x34
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
16f8: e58d2044 str r2, [sp, #68] ; 0x44
16fc: eaffff61 b 1488 <si5351_i2c_probe+0x4a8>
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1700: e3000000 movw r0, #0
1704: e30015e8 movw r1, #1512 ; 0x5e8
1708: e3400000 movt r0, #0
!drvdata->onecell.clks)) {
ret = -ENOMEM;
170c: e3e0500b mvn r5, #11
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1710: ebfffffe bl 0 <warn_slowpath_null>
1714: eaffffbd b 1610 <si5351_i2c_probe+0x630>
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
1718: e5942000 ldr r2, [r4]
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
171c: e3003000 movw r3, #0
1720: e59f96dc ldr r9, [pc, #1756] ; 1e04 <si5351_i2c_probe+0xe24>
1724: e3005000 movw r5, #0
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
1728: e3520004 cmp r2, #4
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
172c: e3002000 movw r2, #0
1730: e3402000 movt r2, #0
1734: e58d201c str r2, [sp, #28]
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
1738: 13a01003 movne r1, #3
173c: 03a01004 moveq r1, #4
1740: e58d1018 str r1, [sp, #24]
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
1744: e3405000 movt r5, #0
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
1748: e59d100c ldr r1, [sp, #12]
parent_names[3] = si5351_input_names[1];
174c: e3403000 movt r3, #0
1750: e5942088 ldr r2, [r4, #136] ; 0x88
1754: e289a070 add sl, r9, #112 ; 0x70
1758: e58db00c str fp, [sp, #12]
for (n = 0; n < num_clocks; n++) {
175c: e3a07000 mov r7, #0
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
1760: e58d102c str r1, [sp, #44] ; 0x2c
parent_names[3] = si5351_input_names[1];
1764: e1a0b004 mov fp, r4
1768: e59d1010 ldr r1, [sp, #16]
176c: e1a04005 mov r4, r5
1770: e1a05009 mov r5, r9
1774: e1a09006 mov r9, r6
1778: e59d6014 ldr r6, [sp, #20]
177c: e58d1030 str r1, [sp, #48] ; 0x30
1780: e1a01003 mov r1, r3
1784: ea000005 b 17a0 <si5351_i2c_probe+0x7c0>
for (n = 0; n < num_clocks; n++) {
1788: e59d3008 ldr r3, [sp, #8]
178c: e1570003 cmp r7, r3
1790: aa000147 bge 1cb4 <si5351_i2c_probe+0xcd4>
1794: e5b51004 ldr r1, [r5, #4]!
1798: e59b2088 ldr r2, [fp, #136] ; 0x88
179c: e5ba4004 ldr r4, [sl, #4]!
17a0: e1a08287 lsl r8, r7, #5
parent_names[0] = si5351_msynth_names[n];
17a4: e58d1024 str r1, [sp, #36] ; 0x24
17a8: e0888107 add r8, r8, r7, lsl #2
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17ac: e59d101c ldr r1, [sp, #28]
17b0: e3570003 cmp r7, #3
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
17b4: e0822008 add r2, r2, r8
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17b8: e3003000 movw r3, #0
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
17bc: e1a00009 mov r0, r9
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17c0: e3403000 movt r3, #0
17c4: d1a01003 movle r1, r3
17c8: e58d1028 str r1, [sp, #40] ; 0x28
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
17cc: e5c27020 strb r7, [r2, #32]
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
17d0: e3a01014 mov r1, #20
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
17d4: e59b2088 ldr r2, [fp, #136] ; 0x88
17d8: e0822008 add r2, r2, r8
17dc: e582b00c str fp, [r2, #12]
drvdata->clkout[n].hw.init = &init;
17e0: e59b2088 ldr r2, [fp, #136] ; 0x88
17e4: e0822008 add r2, r2, r8
17e8: e5829008 str r9, [r2, #8]
memset(&init, 0, sizeof(init));
17ec: ebfffffe bl 0 <__memzero>
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
17f0: e59f3614 ldr r3, [pc, #1556] ; 1e0c <si5351_i2c_probe+0xe2c>
init.flags = 0;
17f4: e3a02000 mov r2, #0
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
17f8: e58d3038 str r3, [sp, #56] ; 0x38
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
17fc: e59d3000 ldr r3, [sp]
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
1800: e58d2044 str r2, [sp, #68] ; 0x44
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
1804: e58d4034 str r4, [sp, #52] ; 0x34
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
1808: e596200c ldr r2, [r6, #12]
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
180c: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = num_parents;
1810: e5dd3018 ldrb r3, [sp, #24]
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
1814: e3520001 cmp r2, #1
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
1818: e59d000c ldr r0, [sp, #12]
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
init.flags |= CLK_SET_RATE_PARENT;
181c: 03a02004 moveq r2, #4
1820: 058d2044 streq r2, [sp, #68] ; 0x44
init.parent_names = parent_names;
init.num_parents = num_parents;
1824: e5cd3040 strb r3, [sp, #64] ; 0x40
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
1828: e59b1088 ldr r1, [fp, #136] ; 0x88
182c: e0811008 add r1, r1, r8
1830: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1834: e3700a01 cmn r0, #4096 ; 0x1000
1838: 8a000035 bhi 1914 <si5351_i2c_probe+0x934>
dev_err(&client->dev, "unable to register %s\n",
init.name);
ret = PTR_ERR(clk);
goto err_clk;
}
drvdata->onecell.clks[n] = clk;
183c: e59b100c ldr r1, [fp, #12]
1840: e2866018 add r6, r6, #24
1844: e7810107 str r0, [r1, r7, lsl #2]
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
1848: e2877001 add r7, r7, #1
goto err_clk;
}
drvdata->onecell.clks[n] = clk;
/* set initial clkout rate */
if (pdata->clkout[n].rate != 0) {
184c: e5961004 ldr r1, [r6, #4]
1850: e3510000 cmp r1, #0
1854: 0affffcb beq 1788 <si5351_i2c_probe+0x7a8>
int ret;
ret = clk_set_rate(clk, pdata->clkout[n].rate);
1858: ebfffffe bl 0 <clk_set_rate>
if (ret != 0) {
185c: e2502000 subs r2, r0, #0
1860: 0affffc8 beq 1788 <si5351_i2c_probe+0x7a8>
dev_err(&client->dev, "Cannot set rate : %d\n",
1864: e3001000 movw r1, #0
1868: e59d000c ldr r0, [sp, #12]
186c: e3401000 movt r1, #0
1870: ebfffffe bl 0 <dev_err>
1874: eaffffc3 b 1788 <si5351_i2c_probe+0x7a8>
/*
* Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
* VARIANT_C can have CLKIN instead.
*/
if (IS_ERR(drvdata->pxtal) &&
1878: e5943000 ldr r3, [r4]
187c: e3530004 cmp r3, #4
1880: 1a000001 bne 188c <si5351_i2c_probe+0x8ac>
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
1884: e3700a01 cmn r0, #4096 ; 0x1000
1888: 9afffe40 bls 1190 <si5351_i2c_probe+0x1b0>
dev_err(&client->dev, "missing parent clock\n");
188c: e3001000 movw r1, #0
1890: e1a0000b mov r0, fp
1894: e3401000 movt r1, #0
1898: ebfffffe bl 0 <dev_err>
return -EINVAL;
189c: e3e00015 mvn r0, #21
18a0: eafffe14 b 10f8 <si5351_i2c_probe+0x118>
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
if (IS_ERR(drvdata->regmap)) {
dev_err(&client->dev, "failed to allocate register map\n");
18a4: e3001000 movw r1, #0
18a8: e1a0000b mov r0, fp
18ac: e3401000 movt r1, #0
18b0: ebfffffe bl 0 <dev_err>
return (void *) error;
}
static inline long __must_check PTR_ERR(__force const void *ptr)
{
return (long) ptr;
18b4: e5940008 ldr r0, [r4, #8]
return PTR_ERR(drvdata->regmap);
18b8: eafffe0e b 10f8 <si5351_i2c_probe+0x118>
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
if (ret) {
18bc: e3a02000 mov r2, #0
dev_err(&client->dev,
18c0: e3001000 movw r1, #0
18c4: e1a0000b mov r0, fp
18c8: e7983102 ldr r3, [r8, r2, lsl #2]
18cc: e3401000 movt r1, #0
18d0: ebfffffe bl 0 <dev_err>
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
18d4: e1a00007 mov r0, r7
if (ret) {
dev_err(&client->dev,
"failed to reparent pll %d to %d\n",
n, pdata->pll_src[n]);
return ret;
18d8: eafffe06 b 10f8 <si5351_i2c_probe+0x118>
err_clk:
if (!IS_ERR(drvdata->pxtal))
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_disable_unprepare(drvdata->pclkin);
return ret;
18dc: e1a00005 mov r0, r5
18e0: eafffe04 b 10f8 <si5351_i2c_probe+0x118>
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
18e4: e1a03287 lsl r3, r7, #5
}
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
18e8: e3001000 movw r1, #0
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
18ec: e0433187 sub r3, r3, r7, lsl #3
18f0: e1a04000 mov r4, r0
18f4: e0888003 add r8, r8, r3
}
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
18f8: e1a0000b mov r0, fp
18fc: e1a02007 mov r2, r7
1900: e3401000 movt r1, #0
1904: e598300c ldr r3, [r8, #12]
1908: ebfffffe bl 0 <dev_err>
"failed to reparent multisynth %d to %d\n",
n, pdata->clkout[n].multisynth_src);
return ret;
}
ret = _si5351_clkout_reparent(drvdata, n,
190c: e1a00004 mov r0, r4
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
return ret;
1910: eafffdf8 b 10f8 <si5351_i2c_probe+0x118>
1914: e1a0400b mov r4, fp
1918: e1a05000 mov r5, r0
191c: e59db00c ldr fp, [sp, #12]
1920: eaffff35 b 15fc <si5351_i2c_probe+0x61c>
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1924: e3a01000 mov r1, #0
1928: e1a00005 mov r0, r5
192c: ebfffffe bl 0 <of_get_next_child>
1930: e2504000 subs r4, r0, #0
1934: 159d9000 ldrne r9, [sp]
1938: 0a000099 beq 1ba4 <si5351_i2c_probe+0xbc4>
static inline int of_property_read_u32(const struct device_node *np,
const char *propname,
u32 *out_value)
{
return of_property_read_u32_array(np, propname, out_value, 1);
193c: e3001000 movw r1, #0
1940: e3a03001 mov r3, #1
1944: e3401000 movt r1, #0
1948: e1a02009 mov r2, r9
194c: e1a00004 mov r0, r4
1950: ebfffffe bl 0 <of_property_read_u32_array>
if (of_property_read_u32(child, "reg", &num)) {
1954: e3500000 cmp r0, #0
1958: 1a000110 bne 1da0 <si5351_i2c_probe+0xdc0>
dev_err(&client->dev, "missing reg property of %s\n",
child->name);
return -EINVAL;
}
if (num >= 8 ||
195c: e59d2024 ldr r2, [sp, #36] ; 0x24
1960: e3520007 cmp r2, #7
1964: ca000107 bgt 1d88 <si5351_i2c_probe+0xda8>
(variant == SI5351_VARIANT_A3 && num >= 3)) {
1968: e3520002 cmp r2, #2
196c: d3a03000 movle r3, #0
1970: c3a03001 movgt r3, #1
1974: e3570002 cmp r7, #2
1978: 13a03000 movne r3, #0
197c: e3530000 cmp r3, #0
1980: 1a000100 bne 1d88 <si5351_i2c_probe+0xda8>
1984: e28d6034 add r6, sp, #52 ; 0x34
1988: e3001000 movw r1, #0
198c: e3401000 movt r1, #0
1990: e3a03001 mov r3, #1
1994: e1a02006 mov r2, r6
1998: e1a00004 mov r0, r4
199c: ebfffffe bl 0 <of_property_read_u32_array>
dev_err(&client->dev, "invalid clkout %d\n", num);
return -EINVAL;
}
if (!of_property_read_u32(child, "silabs,multisynth-source",
19a0: e3500000 cmp r0, #0
19a4: 1a00000a bne 19d4 <si5351_i2c_probe+0x9f4>
&val)) {
switch (val) {
19a8: e59d2034 ldr r2, [sp, #52] ; 0x34
19ac: e3520000 cmp r2, #0
19b0: 0a0000d5 beq 1d0c <si5351_i2c_probe+0xd2c>
19b4: e3520001 cmp r2, #1
19b8: 1a0000cc bne 1cf0 <si5351_i2c_probe+0xd10>
case 0:
pdata->clkout[num].multisynth_src =
SI5351_MULTISYNTH_SRC_VCO0;
break;
case 1:
pdata->clkout[num].multisynth_src =
19bc: e59d2024 ldr r2, [sp, #36] ; 0x24
19c0: e3a01002 mov r1, #2
19c4: e1a03282 lsl r3, r2, #5
19c8: e0433182 sub r3, r3, r2, lsl #3
19cc: e0883003 add r3, r8, r3
19d0: e5831008 str r1, [r3, #8]
19d4: e3001000 movw r1, #0
19d8: e3a03001 mov r3, #1
19dc: e3401000 movt r1, #0
19e0: e1a02006 mov r2, r6
19e4: e1a00004 mov r0, r4
19e8: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
19ec: e3500000 cmp r0, #0
19f0: 1a00000e bne 1a30 <si5351_i2c_probe+0xa50>
switch (val) {
19f4: e59d2034 ldr r2, [sp, #52] ; 0x34
19f8: e3520003 cmp r2, #3
19fc: 979ff102 ldrls pc, [pc, r2, lsl #2]
1a00: ea0000cc b 1d38 <si5351_i2c_probe+0xd58>
1a04: 00001af8 .word 0x00001af8
1a08: 00001adc .word 0x00001adc
1a0c: 00001ac0 .word 0x00001ac0
1a10: 00001a14 .word 0x00001a14
case 2:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_XTAL;
break;
case 3:
if (variant != SI5351_VARIANT_C) {
1a14: e3570004 cmp r7, #4
1a18: 1a0000ee bne 1dd8 <si5351_i2c_probe+0xdf8>
dev_err(&client->dev,
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
}
pdata->clkout[num].clkout_src =
1a1c: e59d2024 ldr r2, [sp, #36] ; 0x24
1a20: e1a03282 lsl r3, r2, #5
1a24: e0433182 sub r3, r3, r2, lsl #3
1a28: e0883003 add r3, r8, r3
1a2c: e583700c str r7, [r3, #12]
1a30: e3001000 movw r1, #0
1a34: e3a03001 mov r3, #1
1a38: e3401000 movt r1, #0
1a3c: e1a02006 mov r2, r6
1a40: e1a00004 mov r0, r4
1a44: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,drive-strength",
1a48: e3500000 cmp r0, #0
1a4c: 1a00000b bne 1a80 <si5351_i2c_probe+0xaa0>
&val)) {
switch (val) {
1a50: e59d2034 ldr r2, [sp, #52] ; 0x34
1a54: e3520008 cmp r2, #8
1a58: 8a0000d7 bhi 1dbc <si5351_i2c_probe+0xddc>
1a5c: e3a03001 mov r3, #1
1a60: e1a03213 lsl r3, r3, r2
1a64: e3130f55 tst r3, #340 ; 0x154
1a68: 0a0000d3 beq 1dbc <si5351_i2c_probe+0xddc>
case SI5351_DRIVE_2MA:
case SI5351_DRIVE_4MA:
case SI5351_DRIVE_6MA:
case SI5351_DRIVE_8MA:
pdata->clkout[num].drive = val;
1a6c: e59d1024 ldr r1, [sp, #36] ; 0x24
1a70: e1a03281 lsl r3, r1, #5
1a74: e0433181 sub r3, r3, r1, lsl #3
1a78: e0883003 add r3, r8, r3
1a7c: e5832010 str r2, [r3, #16]
1a80: e3001000 movw r1, #0
1a84: e3a03001 mov r3, #1
1a88: e3401000 movt r1, #0
1a8c: e1a02006 mov r2, r6
1a90: e1a00004 mov r0, r4
1a94: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,disable-state",
1a98: e3500000 cmp r0, #0
1a9c: 1a000022 bne 1b2c <si5351_i2c_probe+0xb4c>
&val)) {
switch (val) {
1aa0: e59d2034 ldr r2, [sp, #52] ; 0x34
1aa4: e3520003 cmp r2, #3
1aa8: 979ff102 ldrls pc, [pc, r2, lsl #2]
1aac: ea0000a8 b 1d54 <si5351_i2c_probe+0xd74>
1ab0: 00001be8 .word 0x00001be8
1ab4: 00001bcc .word 0x00001bcc
1ab8: 00001bb0 .word 0x00001bb0
1abc: 00001b14 .word 0x00001b14
case 1:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_MSYNTH_0_4;
break;
case 2:
pdata->clkout[num].clkout_src =
1ac0: e59d2024 ldr r2, [sp, #36] ; 0x24
1ac4: e3a01003 mov r1, #3
1ac8: e1a03282 lsl r3, r2, #5
1acc: e0433182 sub r3, r3, r2, lsl #3
1ad0: e0883003 add r3, r8, r3
1ad4: e583100c str r1, [r3, #12]
1ad8: eaffffd4 b 1a30 <si5351_i2c_probe+0xa50>
case 0:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_MSYNTH_N;
break;
case 1:
pdata->clkout[num].clkout_src =
1adc: e59d2024 ldr r2, [sp, #36] ; 0x24
1ae0: e3a01002 mov r1, #2
1ae4: e1a03282 lsl r3, r2, #5
1ae8: e0433182 sub r3, r3, r2, lsl #3
1aec: e0883003 add r3, r8, r3
1af0: e583100c str r1, [r3, #12]
1af4: eaffffcd b 1a30 <si5351_i2c_probe+0xa50>
}
if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
switch (val) {
case 0:
pdata->clkout[num].clkout_src =
1af8: e59d2024 ldr r2, [sp, #36] ; 0x24
1afc: e3a01001 mov r1, #1
1b00: e1a03282 lsl r3, r2, #5
1b04: e0433182 sub r3, r3, r2, lsl #3
1b08: e0883003 add r3, r8, r3
1b0c: e583100c str r1, [r3, #12]
1b10: eaffffc6 b 1a30 <si5351_i2c_probe+0xa50>
case 2:
pdata->clkout[num].disable_state =
SI5351_DISABLE_FLOATING;
break;
case 3:
pdata->clkout[num].disable_state =
1b14: e59d2024 ldr r2, [sp, #36] ; 0x24
1b18: e3a01004 mov r1, #4
1b1c: e1a03282 lsl r3, r2, #5
1b20: e0433182 sub r3, r3, r2, lsl #3
1b24: e0883003 add r3, r8, r3
1b28: e5831014 str r1, [r3, #20]
1b2c: e3001000 movw r1, #0
1b30: e3a03001 mov r3, #1
1b34: e1a02006 mov r2, r6
1b38: e3401000 movt r1, #0
1b3c: e1a00004 mov r0, r4
1b40: ebfffffe bl 0 <of_property_read_u32_array>
* Returns true if the property exist false otherwise.
*/
static inline bool of_property_read_bool(const struct device_node *np,
const char *propname)
{
struct property *prop = of_find_property(np, propname, NULL);
1b44: e3001000 movw r1, #0
1b48: e3401000 movt r1, #0
return -EINVAL;
}
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
1b4c: e59d6024 ldr r6, [sp, #36] ; 0x24
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "clock-frequency", &val))
1b50: e3500000 cmp r0, #0
1b54: e1a00004 mov r0, r4
pdata->clkout[num].rate = val;
1b58: 02866001 addeq r6, r6, #1
1b5c: 059d2034 ldreq r2, [sp, #52] ; 0x34
1b60: 12866001 addne r6, r6, #1
1b64: 01a03286 lsleq r3, r6, #5
1b68: 00433186 subeq r3, r3, r6, lsl #3
1b6c: 00883003 addeq r3, r8, r3
1b70: 05832004 streq r2, [r3, #4]
1b74: e3a02000 mov r2, #0
1b78: ebfffffe bl 0 <of_find_property>
pdata->clkout[num].pll_master =
1b7c: e1a03286 lsl r3, r6, #5
1b80: e0436186 sub r6, r3, r6, lsl #3
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1b84: e1a01004 mov r1, r4
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
1b88: e2903000 adds r3, r0, #0
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1b8c: e1a00005 mov r0, r5
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
1b90: 13a03001 movne r3, #1
1b94: e7c83006 strb r3, [r8, r6]
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1b98: ebfffffe bl 0 <of_get_next_child>
1b9c: e2504000 subs r4, r0, #0
1ba0: 1affff65 bne 193c <si5351_i2c_probe+0x95c>
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
of_property_read_bool(child, "silabs,pll-master");
}
client->dev.platform_data = pdata;
1ba4: e59d3004 ldr r3, [sp, #4]
1ba8: e58380a0 str r8, [r3, #160] ; 0xa0
1bac: eafffd5b b 1120 <si5351_i2c_probe+0x140>
case 1:
pdata->clkout[num].disable_state =
SI5351_DISABLE_HIGH;
break;
case 2:
pdata->clkout[num].disable_state =
1bb0: e59d2024 ldr r2, [sp, #36] ; 0x24
1bb4: e3a01003 mov r1, #3
1bb8: e1a03282 lsl r3, r2, #5
1bbc: e0433182 sub r3, r3, r2, lsl #3
1bc0: e0883003 add r3, r8, r3
1bc4: e5831014 str r1, [r3, #20]
1bc8: eaffffd7 b 1b2c <si5351_i2c_probe+0xb4c>
case 0:
pdata->clkout[num].disable_state =
SI5351_DISABLE_LOW;
break;
case 1:
pdata->clkout[num].disable_state =
1bcc: e59d2024 ldr r2, [sp, #36] ; 0x24
1bd0: e3a01002 mov r1, #2
1bd4: e1a03282 lsl r3, r2, #5
1bd8: e0433182 sub r3, r3, r2, lsl #3
1bdc: e0883003 add r3, r8, r3
1be0: e5831014 str r1, [r3, #20]
1be4: eaffffd0 b 1b2c <si5351_i2c_probe+0xb4c>
if (!of_property_read_u32(child, "silabs,disable-state",
&val)) {
switch (val) {
case 0:
pdata->clkout[num].disable_state =
1be8: e59d2024 ldr r2, [sp, #36] ; 0x24
1bec: e3a01001 mov r1, #1
1bf0: e1a03282 lsl r3, r2, #5
1bf4: e0433182 sub r3, r3, r2, lsl #3
1bf8: e0883003 add r3, r8, r3
1bfc: e5831014 str r1, [r3, #20]
1c00: eaffffc9 b 1b2c <si5351_i2c_probe+0xb4c>
return -EINVAL;
}
p = of_prop_next_u32(prop, p, &val);
if (!p) {
dev_err(&client->dev,
1c04: e3001000 movw r1, #0
1c08: e1a0000b mov r0, fp
1c0c: e3401000 movt r1, #0
1c10: e59d2024 ldr r2, [sp, #36] ; 0x24
1c14: ebfffffe bl 0 <dev_err>
"missing pll-source for pll %d\n", num);
return -EINVAL;
1c18: e3e00015 mvn r0, #21
1c1c: eafffd35 b 10f8 <si5351_i2c_probe+0x118>
goto err_clk;
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
1c20: e1a00006 mov r0, r6
1c24: e3a01014 mov r1, #20
1c28: ebfffffe bl 0 <__memzero>
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
1c2c: e59f31dc ldr r3, [pc, #476] ; 1e10 <si5351_i2c_probe+0xe30>
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c30: e3002000 movw r2, #0
1c34: e3402000 movt r2, #0
init.ops = &si5351_clkin_ops;
1c38: e58d3038 str r3, [sp, #56] ; 0x38
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c3c: e58d2034 str r2, [sp, #52] ; 0x34
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
1c40: e5940028 ldr r0, [r4, #40] ; 0x28
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c44: e58d2010 str r2, [sp, #16]
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
1c48: e3700a01 cmn r0, #4096 ; 0x1000
1c4c: 8a000005 bhi 1c68 <si5351_i2c_probe+0xc88>
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
1c50: ebfffffe bl 0 <__clk_get_name>
1c54: e1a03004 mov r3, r4
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
1c58: e3a02001 mov r2, #1
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
1c5c: e5a3002c str r0, [r3, #44]! ; 0x2c
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
1c60: e5cd2040 strb r2, [sp, #64] ; 0x40
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
init.parent_names = &drvdata->pclkin_name;
1c64: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = 1;
}
drvdata->clkin.init = &init;
1c68: e5846038 str r6, [r4, #56] ; 0x38
clk = devm_clk_register(&client->dev, &drvdata->clkin);
1c6c: e2841030 add r1, r4, #48 ; 0x30
1c70: e1a0000b mov r0, fp
1c74: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1c78: e3700a01 cmn r0, #4096 ; 0x1000
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
}
drvdata->clkin.init = &init;
clk = devm_clk_register(&client->dev, &drvdata->clkin);
1c7c: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
1c80: 8afffe5d bhi 15fc <si5351_i2c_probe+0x61c>
goto err_clk;
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
1c84: e5943000 ldr r3, [r4]
1c88: e3530004 cmp r3, #4
1c8c: 03a05002 moveq r5, #2
1c90: 0afffdce beq 13d0 <si5351_i2c_probe+0x3f0>
1c94: eafffdcc b 13cc <si5351_i2c_probe+0x3ec>
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
if (IS_ERR(clk)) {
dev_err(&client->dev, "unable to register %s\n", init.name);
1c98: e3001000 movw r1, #0
1c9c: e1a0000b mov r0, fp
1ca0: e3401000 movt r1, #0
1ca4: e59d2034 ldr r2, [sp, #52] ; 0x34
1ca8: e1a05003 mov r5, r3
1cac: ebfffffe bl 0 <dev_err>
ret = PTR_ERR(clk);
goto err_clk;
1cb0: eafffe56 b 1610 <si5351_i2c_probe+0x630>
ret);
}
}
}
ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
1cb4: e59d3004 ldr r3, [sp, #4]
1cb8: e3001000 movw r1, #0
1cbc: e1a0400b mov r4, fp
1cc0: e3401000 movt r1, #0
1cc4: e284200c add r2, r4, #12
1cc8: e59db00c ldr fp, [sp, #12]
1ccc: e5930204 ldr r0, [r3, #516] ; 0x204
1cd0: ebfffffe bl 0 <of_clk_add_provider>
&drvdata->onecell);
if (ret) {
1cd4: e2505000 subs r5, r0, #0
1cd8: 0afffeff beq 18dc <si5351_i2c_probe+0x8fc>
dev_err(&client->dev, "unable to add clk provider\n");
1cdc: e3001000 movw r1, #0
1ce0: e1a0000b mov r0, fp
1ce4: e3401000 movt r1, #0
1ce8: ebfffffe bl 0 <dev_err>
goto err_clk;
1cec: eafffe47 b 1610 <si5351_i2c_probe+0x630>
case 1:
pdata->clkout[num].multisynth_src =
SI5351_MULTISYNTH_SRC_VCO1;
break;
default:
dev_err(&client->dev,
1cf0: e3001000 movw r1, #0
1cf4: e1a0000b mov r0, fp
1cf8: e3401000 movt r1, #0
1cfc: e59d3024 ldr r3, [sp, #36] ; 0x24
1d00: ebfffffe bl 0 <dev_err>
"invalid parent %d for multisynth %d\n",
val, num);
return -EINVAL;
1d04: e3e00015 mvn r0, #21
1d08: eafffcfa b 10f8 <si5351_i2c_probe+0x118>
if (!of_property_read_u32(child, "silabs,multisynth-source",
&val)) {
switch (val) {
case 0:
pdata->clkout[num].multisynth_src =
1d0c: e59d2024 ldr r2, [sp, #36] ; 0x24
1d10: e3a01001 mov r1, #1
1d14: e1a03282 lsl r3, r2, #5
1d18: e0433182 sub r3, r3, r2, lsl #3
1d1c: e0883003 add r3, r8, r3
1d20: e5831008 str r1, [r3, #8]
1d24: eaffff2a b 19d4 <si5351_i2c_probe+0x9f4>
if (np == NULL)
return 0;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
1d28: e3e0000b mvn r0, #11
1d2c: eafffcf1 b 10f8 <si5351_i2c_probe+0x118>
if (ret)
return ret;
pdata = client->dev.platform_data;
if (!pdata)
return -EINVAL;
1d30: e3e00015 mvn r0, #21
1d34: eafffcef b 10f8 <si5351_i2c_probe+0x118>
}
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_CLKIN;
break;
default:
dev_err(&client->dev,
1d38: e3001000 movw r1, #0
1d3c: e1a0000b mov r0, fp
1d40: e3401000 movt r1, #0
1d44: e59d3024 ldr r3, [sp, #36] ; 0x24
1d48: ebfffffe bl 0 <dev_err>
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
1d4c: e3e00015 mvn r0, #21
1d50: eafffce8 b 10f8 <si5351_i2c_probe+0x118>
case 3:
pdata->clkout[num].disable_state =
SI5351_DISABLE_NEVER;
break;
default:
dev_err(&client->dev,
1d54: e3001000 movw r1, #0
1d58: e1a0000b mov r0, fp
1d5c: e3401000 movt r1, #0
1d60: e59d3024 ldr r3, [sp, #36] ; 0x24
1d64: ebfffffe bl 0 <dev_err>
"invalid disable state %d for clkout %d\n",
val, num);
return -EINVAL;
1d68: e3e00015 mvn r0, #21
1d6c: eafffce1 b 10f8 <si5351_i2c_probe+0x118>
if (!pdata)
return -EINVAL;
drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&client->dev, "unable to allocate driver data\n");
1d70: e3001000 movw r1, #0
1d74: e1a0000b mov r0, fp
1d78: e3401000 movt r1, #0
1d7c: ebfffffe bl 0 <dev_err>
return -ENOMEM;
1d80: e3e0000b mvn r0, #11
1d84: eafffcdb b 10f8 <si5351_i2c_probe+0x118>
return -EINVAL;
}
if (num >= 8 ||
(variant == SI5351_VARIANT_A3 && num >= 3)) {
dev_err(&client->dev, "invalid clkout %d\n", num);
1d88: e3001000 movw r1, #0
1d8c: e1a0000b mov r0, fp
1d90: e3401000 movt r1, #0
1d94: ebfffffe bl 0 <dev_err>
return -EINVAL;
1d98: e3e00015 mvn r0, #21
1d9c: eafffcd5 b 10f8 <si5351_i2c_probe+0x118>
}
/* per clkout properties */
for_each_child_of_node(np, child) {
if (of_property_read_u32(child, "reg", &num)) {
dev_err(&client->dev, "missing reg property of %s\n",
1da0: e3001000 movw r1, #0
1da4: e1a0000b mov r0, fp
1da8: e5942000 ldr r2, [r4]
1dac: e3401000 movt r1, #0
1db0: ebfffffe bl 0 <dev_err>
child->name);
return -EINVAL;
1db4: e3e00015 mvn r0, #21
1db8: eafffcce b 10f8 <si5351_i2c_probe+0x118>
case SI5351_DRIVE_6MA:
case SI5351_DRIVE_8MA:
pdata->clkout[num].drive = val;
break;
default:
dev_err(&client->dev,
1dbc: e3001000 movw r1, #0
1dc0: e1a0000b mov r0, fp
1dc4: e3401000 movt r1, #0
1dc8: e59d3024 ldr r3, [sp, #36] ; 0x24
1dcc: ebfffffe bl 0 <dev_err>
"invalid drive strength %d for clkout %d\n",
val, num);
return -EINVAL;
1dd0: e3e00015 mvn r0, #21
1dd4: eafffcc7 b 10f8 <si5351_i2c_probe+0x118>
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_XTAL;
break;
case 3:
if (variant != SI5351_VARIANT_C) {
dev_err(&client->dev,
1dd8: e3001000 movw r1, #0
1ddc: e1a0000b mov r0, fp
1de0: e3401000 movt r1, #0
1de4: e59d3024 ldr r3, [sp, #36] ; 0x24
1de8: e3a02003 mov r2, #3
1dec: ebfffffe bl 0 <dev_err>
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
1df0: e3e00015 mvn r0, #21
1df4: eafffcbf b 10f8 <si5351_i2c_probe+0x118>
1df8: 00000034 .word 0x00000034
1dfc: 000000ac .word 0x000000ac
1e00: 0000014c .word 0x0000014c
1e04: 000001ec .word 0x000001ec
1e08: 0000020c .word 0x0000020c
1e0c: 0000027c .word 0x0000027c
1e10: 000000fc .word 0x000000fc
00001e14 <si5351_msynth_set_parent>:
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e14: e3510000 cmp r1, #0
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
1e18: e92d4010 push {r4, lr}
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e1c: e5d02020 ldrb r2, [r0, #32]
1e20: 1a000003 bne 1e34 <si5351_msynth_set_parent+0x20>
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e24: e3520008 cmp r2, #8
1e28: da00000c ble 1e60 <si5351_msynth_set_parent+0x4c>
return -EINVAL;
1e2c: e3e00015 mvn r0, #21
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e30: e8bd8010 pop {r4, pc}
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e34: e3520008 cmp r2, #8
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1e38: d2822010 addle r2, r2, #16
1e3c: d3a03020 movle r3, #32
1e40: d6ef1072 uxtble r1, r2
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e44: cafffff8 bgt 1e2c <si5351_msynth_set_parent+0x18>
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1e48: e590000c ldr r0, [r0, #12]
1e4c: e3a02020 mov r2, #32
1e50: e5900008 ldr r0, [r0, #8]
1e54: ebfffffe bl 0 <regmap_update_bits>
1e58: e3a00000 mov r0, #0
1e5c: e8bd8010 pop {r4, pc}
return 0;
if (num > 8)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1e60: e2822010 add r2, r2, #16
1e64: e1a03001 mov r3, r1
1e68: e6ef1072 uxtb r1, r2
1e6c: eafffff5 b 1e48 <si5351_msynth_set_parent+0x34>
Disassembly of section .init.text:
00000000 <si5351_driver_init>:
}
}
static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
0: e3001000 movw r1, #0
4: e3a00000 mov r0, #0
8: e3401000 movt r1, #0
c: eafffffe b 0 <i2c_register_driver>
Disassembly of section .exit.text:
00000000 <si5351_driver_exit>:
0: e3000000 movw r0, #0
4: e3400000 movt r0, #0
8: eafffffe b 0 <i2c_del_driver>
-------------- next part --------------
./drivers/clk/clk-si5351.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <si5351_regmap_is_volatile>:
}
}
static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
0: e3510001 cmp r1, #1
4: 9a000003 bls 18 <si5351_regmap_is_volatile+0x18>
8: e35100b1 cmp r1, #177 ; 0xb1
c: 0a000001 beq 18 <si5351_regmap_is_volatile+0x18>
case SI5351_DEVICE_STATUS:
case SI5351_INTERRUPT_STATUS:
case SI5351_PLL_RESET:
return true;
}
return false;
10: e3a00000 mov r0, #0
14: e12fff1e bx lr
{
switch (reg) {
case SI5351_DEVICE_STATUS:
case SI5351_INTERRUPT_STATUS:
case SI5351_PLL_RESET:
return true;
18: e3a00001 mov r0, #1
}
return false;
}
1c: e12fff1e bx lr
00000020 <si5351_vxco_unprepare>:
return 0;
}
static void si5351_vxco_unprepare(struct clk_hw *hw)
{
20: e12fff1e bx lr
00000024 <si5351_vxco_recalc_rate>:
static unsigned long si5351_vxco_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return 0;
}
24: e3a00000 mov r0, #0
28: e12fff1e bx lr
0000002c <si5351_vxco_set_rate>:
static int si5351_vxco_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent)
{
return 0;
}
2c: e3a00000 mov r0, #0
30: e12fff1e bx lr
00000034 <si5351_pll_get_parent>:
(parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
return 0;
}
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
34: e92d4030 push {r4, r5, lr}
38: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
3c: e5d03020 ldrb r3, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
40: e28d2004 add r2, sp, #4
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
44: e590400c ldr r4, [r0, #12]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
48: e3a0100f mov r1, #15
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
4c: e3530000 cmp r3, #0
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
50: e5940008 ldr r0, [r4, #8]
static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
54: 13a05008 movne r5, #8
58: 03a05004 moveq r5, #4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
5c: ebfffffe bl 0 <regmap_read>
if (ret) {
60: e3500000 cmp r0, #0
64: 1a000005 bne 80 <si5351_pll_get_parent+0x4c>
68: e59d3004 ldr r3, [sp, #4]
6c: e1150003 tst r5, r3
70: 13a00001 movne r0, #1
74: 03a00000 moveq r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
return (val & mask) ? 1 : 0;
}
78: e28dd00c add sp, sp, #12
7c: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
80: e5940004 ldr r0, [r4, #4]
84: e3001000 movw r1, #0
88: e3401000 movt r1, #0
8c: e3a0200f mov r2, #15
90: e2800020 add r0, r0, #32
94: ebfffffe bl 0 <dev_err>
98: e3a00000 mov r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
return (val & mask) ? 1 : 0;
}
9c: e28dd00c add sp, sp, #12
a0: e8bd8030 pop {r4, r5, pc}
000000a4 <si5351_msynth_get_parent>:
SI5351_CLK_PLL_SELECT);
return 0;
}
static unsigned char si5351_msynth_get_parent(struct clk_hw *hw)
{
a4: e92d4030 push {r4, r5, lr}
a8: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
ac: e5d04020 ldrb r4, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
b0: e28d2004 add r2, sp, #4
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
b4: e590500c ldr r5, [r0, #12]
b8: e2844010 add r4, r4, #16
bc: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c0: e5950008 ldr r0, [r5, #8]
c4: e1a01004 mov r1, r4
c8: ebfffffe bl 0 <regmap_read>
if (ret) {
cc: e3500000 cmp r0, #0
d0: 05dd0004 ldrbeq r0, [sp, #4]
d4: 07e002d0 ubfxeq r0, r0, #5, #1
d8: 1a000001 bne e4 <si5351_msynth_get_parent+0x40>
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
dc: e28dd00c add sp, sp, #12
e0: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
e4: e5950004 ldr r0, [r5, #4]
e8: e3001000 movw r1, #0
ec: e1a02004 mov r2, r4
f0: e3401000 movt r1, #0
f4: e2800020 add r0, r0, #32
f8: ebfffffe bl 0 <dev_err>
fc: e3a00000 mov r0, #0
u8 val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
100: e28dd00c add sp, sp, #12
104: e8bd8030 pop {r4, r5, pc}
00000108 <si5351_clkout_get_parent>:
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), (1 << hwdata->num));
}
static u8 si5351_clkout_get_parent(struct clk_hw *hw)
{
108: e92d4030 push {r4, r5, lr}
10c: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
int index = 0;
unsigned char val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
110: e5d04020 ldrb r4, [r0, #32]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
114: e28d2004 add r2, sp, #4
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
int index = 0;
unsigned char val;
val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
118: e590500c ldr r5, [r0, #12]
11c: e2844010 add r4, r4, #16
120: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
124: e5950008 ldr r0, [r5, #8]
128: e1a01004 mov r1, r4
12c: ebfffffe bl 0 <regmap_read>
if (ret) {
130: e3500000 cmp r0, #0
134: 1a000007 bne 158 <si5351_clkout_get_parent+0x50>
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
138: e5dd3004 ldrb r3, [sp, #4]
13c: e203300c and r3, r3, #12
140: e3530008 cmp r3, #8
144: 93002000 movwls r2, #0
148: 93402000 movtls r2, #0
14c: 97d20103 ldrbls r0, [r2, r3, lsl #2]
index = 3;
break;
}
return index;
}
150: e28dd00c add sp, sp, #12
154: e8bd8030 pop {r4, r5, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
158: e5950004 ldr r0, [r5, #4]
15c: e3001000 movw r1, #0
160: e1a02004 mov r2, r4
164: e3401000 movt r1, #0
168: e2800020 add r0, r0, #32
16c: ebfffffe bl 0 <dev_err>
170: e3a00002 mov r0, #2
index = 3;
break;
}
return index;
}
174: e28dd00c add sp, sp, #12
178: e8bd8030 pop {r4, r5, pc}
0000017c <si5351_clkout_recalc_rate>:
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
17c: e92d40f0 push {r4, r5, r6, r7, lr}
180: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
184: e5d03020 ldrb r3, [r0, #32]
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
188: e1a06001 mov r6, r1
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
rdiv = si5351_reg_read(hwdata->drvdata, reg);
18c: e590700c ldr r7, [r0, #12]
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
}
static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
190: e1a05000 mov r5, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
194: e3530005 cmp r3, #5
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
198: e28d2004 add r2, sp, #4
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
19c: 91a04183 lslls r4, r3, #3
1a0: 9284402c addls r4, r4, #44 ; 0x2c
1a4: 83a0105c movhi r1, #92 ; 0x5c
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
1a8: e5970008 ldr r0, [r7, #8]
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
1ac: 81a04001 movhi r4, r1
container_of(hw, struct si5351_hw_data, hw);
unsigned char reg;
unsigned char rdiv;
if (hwdata->num <= 5)
reg = si5351_msynth_params_address(hwdata->num) + 2;
1b0: 96ef4074 uxtbls r4, r4
1b4: 91a01004 movls r1, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
1b8: ebfffffe bl 0 <regmap_read>
if (ret) {
1bc: e3500000 cmp r0, #0
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
1c0: 05dd0004 ldrbeq r0, [sp, #4]
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
1c4: 1a000006 bne 1e4 <si5351_clkout_recalc_rate+0x68>
reg = si5351_msynth_params_address(hwdata->num) + 2;
else
reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
rdiv = si5351_reg_read(hwdata->drvdata, reg);
if (hwdata->num == 6) {
1c8: e5d53020 ldrb r3, [r5, #32]
1cc: e3530006 cmp r3, #6
rdiv &= SI5351_OUTPUT_CLK6_DIV_MASK;
1d0: 02000007 andeq r0, r0, #7
} else {
rdiv &= SI5351_OUTPUT_CLK_DIV_MASK;
rdiv >>= SI5351_OUTPUT_CLK_DIV_SHIFT;
1d4: 17e20250 ubfxne r0, r0, #4, #3
}
return parent_rate >> rdiv;
}
1d8: e1a00036 lsr r0, r6, r0
1dc: e28dd00c add sp, sp, #12
1e0: e8bd80f0 pop {r4, r5, r6, r7, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
1e4: e5970004 ldr r0, [r7, #4]
1e8: e3001000 movw r1, #0
1ec: e1a02004 mov r2, r4
1f0: e3401000 movt r1, #0
1f4: e2800020 add r0, r0, #32
1f8: ebfffffe bl 0 <dev_err>
"unable to read from reg%02x\n", reg);
return 0;
1fc: e3a00000 mov r0, #0
200: eafffff0 b 1c8 <si5351_clkout_recalc_rate+0x4c>
00000204 <si5351_clkout_round_rate>:
return parent_rate >> rdiv;
}
static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
204: e92d4030 push {r4, r5, lr}
208: e1a04002 mov r4, r2
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char rdiv;
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
20c: e5d03020 ldrb r3, [r0, #32]
return parent_rate >> rdiv;
}
static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
210: e24dd00c sub sp, sp, #12
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned char rdiv;
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
214: e3530005 cmp r3, #5
218: 9a000017 bls 27c <si5351_clkout_round_rate+0x78>
21c: e30d3180 movw r3, #53632 ; 0xd180
220: e34038f0 movt r3, #2288 ; 0x8f0
224: e1510003 cmp r1, r3
228: 21a01003 movcs r1, r3
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
22c: e3510d7d cmp r1, #8000 ; 0x1f40
230: 2a00003a bcs 320 <si5351_clkout_round_rate+0x11c>
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
234: e5900004 ldr r0, [r0, #4]
238: ebfffffe bl 0 <__clk_get_flags>
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
23c: e3a01d7d mov r1, #8000 ; 0x1f40
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
240: e3100004 tst r0, #4
244: 0a000015 beq 2a0 <si5351_clkout_round_rate+0x9c>
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
248: e304023f movw r0, #16959 ; 0x423f
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
24c: e3a03000 mov r3, #0
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
250: e340000f movt r0, #15
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
254: e2833001 add r3, r3, #1
rate *= 2;
258: e1a01081 lsl r1, r1, #1
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
25c: e6ef3073 uxtb r3, r3
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
260: e1510000 cmp r1, r0
264: 93530006 cmpls r3, #6
268: 9afffff9 bls 254 <si5351_clkout_round_rate+0x50>
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
26c: e1a00331 lsr r0, r1, r3
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
rdiv < SI5351_OUTPUT_CLK_DIV_128) {
rdiv += 1;
rate *= 2;
}
*parent_rate = rate;
270: e5841000 str r1, [r4]
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
}
274: e28dd00c add sp, sp, #12
278: e8bd8030 pop {r4, r5, pc}
/* clkout6/7 can only handle output freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
27c: e3a05b1a mov r5, #26624 ; 0x6800
280: e3405989 movt r5, #2441 ; 0x989
284: e1510005 cmp r1, r5
288: 9affffe7 bls 22c <si5351_clkout_round_rate+0x28>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
28c: e5900004 ldr r0, [r0, #4]
290: ebfffffe bl 0 <__clk_get_flags>
if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
rate = SI5351_CLKOUT67_MAX_FREQ;
/* clkout freqency is 8kHz - 160MHz */
if (rate > SI5351_CLKOUT_MAX_FREQ)
rate = SI5351_CLKOUT_MAX_FREQ;
294: e1a01005 mov r1, r5
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
298: e3100004 tst r0, #4
29c: 1a000029 bne 348 <si5351_clkout_round_rate+0x144>
} else {
unsigned long new_rate, new_err, err;
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
2a0: e5940000 ldr r0, [r4]
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2a4: e0613000 rsb r3, r1, r0
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
2a8: e1a0e0a0 lsr lr, r0, #1
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2ac: e3530000 cmp r3, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2b0: e061400e rsb r4, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2b4: b2633000 rsblt r3, r3, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2b8: e3540000 cmp r4, #0
2bc: b2644000 rsblt r4, r4, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2c0: e1530004 cmp r3, r4
2c4: 3a000012 bcc 314 <si5351_clkout_round_rate+0x110>
2c8: e3a03000 mov r3, #0
break;
rdiv++;
2cc: e2833001 add r3, r3, #1
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
2d0: e1a0e0ae lsr lr, lr, #1
new_err = abs(new_rate - rate);
2d4: e061200e rsb r2, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
break;
rdiv++;
2d8: e6ef3073 uxtb r3, r3
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2dc: e3520000 cmp r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2e0: e243c007 sub ip, r3, #7
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
2e4: b2622000 rsblt r2, r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
2e8: e16fcf1c clz ip, ip
2ec: e1a0c2ac lsr ip, ip, #5
2f0: e1520004 cmp r2, r4
2f4: 838cc001 orrhi ip, ip, #1
2f8: e1a04002 mov r4, r2
2fc: e35c0000 cmp ip, #0
300: 0afffff1 beq 2cc <si5351_clkout_round_rate+0xc8>
304: e1a01000 mov r1, r0
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
*parent_rate, rate);
return rate;
308: e1a00331 lsr r0, r1, r3
}
30c: e28dd00c add sp, sp, #12
310: e8bd8030 pop {r4, r5, pc}
new_rate = *parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
314: e1a01000 mov r1, r0
318: e3a03000 mov r3, #0
31c: eafffff9 b 308 <si5351_clkout_round_rate+0x104>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
320: e5900004 ldr r0, [r0, #4]
324: e58d1004 str r1, [sp, #4]
328: ebfffffe bl 0 <__clk_get_flags>
32c: e3100004 tst r0, #4
330: e59d1004 ldr r1, [sp, #4]
334: 0affffd9 beq 2a0 <si5351_clkout_round_rate+0x9c>
/* use r divider for frequencies below 1MHz */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
338: e304323f movw r3, #16959 ; 0x423f
33c: e340300f movt r3, #15
340: e1510003 cmp r1, r3
344: 9affffbf bls 248 <si5351_clkout_round_rate+0x44>
rate = SI5351_CLKOUT_MAX_FREQ;
if (rate < SI5351_CLKOUT_MIN_FREQ)
rate = SI5351_CLKOUT_MIN_FREQ;
/* request frequency if multisync master */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
348: e3a03000 mov r3, #0
34c: eaffffc6 b 26c <si5351_clkout_round_rate+0x68>
00000350 <si5351_pll_round_rate>:
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
350: e30435ff movw r3, #17919 ; 0x45ff
354: e34233c3 movt r3, #9155 ; 0x23c3
358: e1510003 cmp r1, r3
return (unsigned long)rate;
}
static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
35c: e92d47f0 push {r4, r5, r6, r7, r8, r9, sl, lr}
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
rate = SI5351_PLL_VCO_MIN;
360: 93a05c46 movls r5, #17920 ; 0x4600
return (unsigned long)rate;
}
static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
364: e24dd010 sub sp, sp, #16
368: e1a07000 mov r7, r0
36c: e1a08002 mov r8, r2
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
rate = SI5351_PLL_VCO_MIN;
370: 934253c3 movtls r5, #9155 ; 0x23c3
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
unsigned long rfrac, denom, a, b, c;
unsigned long long lltmp;
if (rate < SI5351_PLL_VCO_MIN)
374: 9a000004 bls 38c <si5351_pll_round_rate+0x3c>
rate = SI5351_PLL_VCO_MIN;
if (rate > SI5351_PLL_VCO_MAX)
rate = SI5351_PLL_VCO_MAX;
378: e3a03ce9 mov r3, #59648 ; 0xe900
37c: e1a05001 mov r5, r1
380: e34335a4 movt r3, #13732 ; 0x35a4
384: e1510003 cmp r1, r3
388: 21a05003 movcs r5, r3
/* determine integer part of feedback equation */
a = rate / *parent_rate;
38c: e5984000 ldr r4, [r8]
390: e1a00005 mov r0, r5
394: e1a01004 mov r1, r4
398: ebfffffe bl 0 <__aeabi_uidiv>
if (a < SI5351_PLL_A_MIN)
39c: e350000e cmp r0, #14
rate = SI5351_PLL_VCO_MIN;
if (rate > SI5351_PLL_VCO_MAX)
rate = SI5351_PLL_VCO_MAX;
/* determine integer part of feedback equation */
a = rate / *parent_rate;
3a0: e1a06000 mov r6, r0
if (a < SI5351_PLL_A_MIN)
rate = *parent_rate * SI5351_PLL_A_MIN;
3a4: 90645204 rsbls r5, r4, r4, lsl #4
rate = SI5351_PLL_VCO_MAX;
/* determine integer part of feedback equation */
a = rate / *parent_rate;
if (a < SI5351_PLL_A_MIN)
3a8: 9a000002 bls 3b8 <si5351_pll_round_rate+0x68>
rate = *parent_rate * SI5351_PLL_A_MIN;
if (a > SI5351_PLL_A_MAX)
3ac: e350005a cmp r0, #90 ; 0x5a
rate = *parent_rate * SI5351_PLL_A_MAX;
3b0: 83a0505a movhi r5, #90 ; 0x5a
3b4: 80050495 mulhi r5, r5, r4
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
3b8: e1a00005 mov r0, r5
3bc: e1a01004 mov r1, r4
lltmp *= denom;
do_div(lltmp, *parent_rate);
3c0: e3049240 movw r9, #16960 ; 0x4240
if (a > SI5351_PLL_A_MAX)
rate = *parent_rate * SI5351_PLL_A_MAX;
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
3c4: ebfffffe bl 0 <__aeabi_uidivmod>
lltmp *= denom;
do_div(lltmp, *parent_rate);
3c8: e340900f movt r9, #15
rfrac = (unsigned long)lltmp;
b = 0;
3cc: e3a03000 mov r3, #0
c = 1;
3d0: e3a05001 mov r5, #1
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
lltmp *= denom;
do_div(lltmp, *parent_rate);
3d4: e0810991 umull r0, r1, r1, r9
rfrac = (unsigned long)lltmp;
b = 0;
3d8: e58d3008 str r3, [sp, #8]
/* find best approximation for b/c = fVCO mod fIN */
denom = 1000 * 1000;
lltmp = rate % (*parent_rate);
lltmp *= denom;
do_div(lltmp, *parent_rate);
3dc: ebfffffe bl 0 <__do_div64>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
3e0: e2520000 subs r0, r2, #0
lltmp *= denom;
do_div(lltmp, *parent_rate);
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
3e4: e58d500c str r5, [sp, #12]
if (rfrac)
3e8: 1a00000e bne 428 <si5351_pll_round_rate+0xd8>
3ec: e1a02000 mov r2, r0
3f0: e3a00cfe mov r0, #65024 ; 0xfe00
3f4: e1a04005 mov r4, r5
3f8: e1a09002 mov r9, r2
3fc: e34f0fff movt r0, #65535 ; 0xffff
/* calculate parameters */
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
400: e0800386 add r0, r0, r6, lsl #7
if (rfrac)
rational_best_approximation(rfrac, denom,
SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);
/* calculate parameters */
hwdata->params.p3 = c;
404: e5874018 str r4, [r7, #24]
hwdata->params.p2 = (128 * b) % c;
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
408: e5870010 str r0, [r7, #16]
rational_best_approximation(rfrac, denom,
SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);
/* calculate parameters */
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
40c: e5879014 str r9, [r7, #20]
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
/* recalculate rate by fIN * (a + b/c) */
lltmp = *parent_rate;
lltmp *= b;
410: e5985000 ldr r5, [r8]
do_div(lltmp, c);
414: e0810295 umull r0, r1, r5, r2
418: ebfffffe bl 0 <__do_div64>
"%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), a, b, c,
*parent_rate, rate);
return rate;
}
41c: e0202695 mla r0, r5, r6, r2
420: e28dd010 add sp, sp, #16
424: e8bd87f0 pop {r4, r5, r6, r7, r8, r9, sl, pc}
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
rational_best_approximation(rfrac, denom,
428: e30f3fff movw r3, #65535 ; 0xffff
42c: e30f2ffe movw r2, #65534 ; 0xfffe
430: e340200f movt r2, #15
434: e28de00c add lr, sp, #12
438: e28dc008 add ip, sp, #8
43c: e1a01009 mov r1, r9
440: e340300f movt r3, #15
444: e88d5000 stm sp, {ip, lr}
448: ebfffffe bl 0 <rational_best_approximation>
44c: e59d5008 ldr r5, [sp, #8]
450: e59d400c ldr r4, [sp, #12]
454: e1a0a385 lsl sl, r5, #7
458: e1a01004 mov r1, r4
45c: e1a0000a mov r0, sl
460: ebfffffe bl 0 <__aeabi_uidivmod>
464: e1a0000a mov r0, sl
468: e1a09001 mov r9, r1
46c: e1a01004 mov r1, r4
470: ebfffffe bl 0 <__aeabi_uidiv>
474: e1a02005 mov r2, r5
478: e2400c02 sub r0, r0, #512 ; 0x200
47c: eaffffdf b 400 <si5351_pll_round_rate+0xb0>
00000480 <si5351_msynth_round_rate>:
return (unsigned long)rate;
}
static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
480: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
484: e1a06000 mov r6, r0
unsigned long long lltmp;
unsigned long a, b, c;
int divby4;
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
488: e5d03020 ldrb r3, [r0, #32]
return (unsigned long)rate;
}
static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
48c: e24dd014 sub sp, sp, #20
490: e1a05001 mov r5, r1
494: e1a09002 mov r9, r2
unsigned long long lltmp;
unsigned long a, b, c;
int divby4;
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
498: e3530005 cmp r3, #5
49c: 9a000027 bls 540 <si5351_msynth_round_rate+0xc0>
4a0: e30d3180 movw r3, #53632 ; 0xd180
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
4a4: e304123f movw r1, #16959 ; 0x423f
4a8: e34038f0 movt r3, #2288 ; 0x8f0
4ac: e1550003 cmp r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
4b0: e3042240 movw r2, #16960 ; 0x4240
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
4b4: e340100f movt r1, #15
4b8: 21a05003 movcs r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
4bc: e1550001 cmp r5, r1
4c0: e340200f movt r2, #15
4c4: 91a05002 movls r5, r2
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
4c8: e5960004 ldr r0, [r6, #4]
4cc: ebfffffe bl 0 <__clk_get_flags>
4d0: e3100004 tst r0, #4
4d4: 0a000024 beq 56c <si5351_msynth_round_rate+0xec>
* find largest integer divider for max
* vco frequency and given target rate
*/
if (divby4 == 0) {
lltmp = SI5351_PLL_VCO_MAX;
do_div(lltmp, rate);
4d8: e1a04005 mov r4, r5
4dc: e28f1054 add r1, pc, #84 ; 0x54
4e0: e1c100d0 ldrd r0, [r1]
4e4: e3a0a000 mov sl, #0
4e8: ebfffffe bl 0 <__do_div64>
4ec: e1a07002 mov r7, r2
a = 4;
b = 0;
c = 1;
*parent_rate = a * rate;
4f0: e0050795 mul r5, r5, r7
do_div(lltmp, rate);
a = (unsigned long)lltmp;
} else
a = 4;
b = 0;
4f4: e3a0b000 mov fp, #0
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
4f8: e1a04007 mov r4, r7
4fc: e1a0100b mov r1, fp
a = (unsigned long)lltmp;
} else
a = 4;
b = 0;
c = 1;
500: e3a08001 mov r8, #1
do_div(lltmp, rate);
a = (unsigned long)lltmp;
} else
a = 4;
b = 0;
504: e58db008 str fp, [sp, #8]
c = 1;
508: e58d800c str r8, [sp, #12]
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
50c: e1a00005 mov r0, r5
a = 4;
b = 0;
c = 1;
*parent_rate = a * rate;
510: e5895000 str r5, [r9]
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
514: ebfffffe bl 0 <__do_div64>
rate = (unsigned long)lltmp;
/* calculate parameters */
if (divby4) {
518: e15a000b cmp sl, fp
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
51c: e1a04002 mov r4, r2
520: 01a0500a moveq r5, sl
rate = (unsigned long)lltmp;
/* calculate parameters */
if (divby4) {
524: 0a00002d beq 5e0 <si5351_msynth_round_rate+0x160>
hwdata->params.p3 = 1;
528: e5868018 str r8, [r6, #24]
hwdata->params.p2 = 0;
52c: e586b014 str fp, [r6, #20]
hwdata->params.p1 = 0;
530: e586b010 str fp, [r6, #16]
534: ea000035 b 610 <si5351_msynth_round_rate+0x190>
538: 35a4e900 .word 0x35a4e900
53c: 00000000 .word 0x00000000
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
540: e3a03b1a mov r3, #26624 ; 0x6800
544: e3403989 movt r3, #2441 ; 0x989
548: e1510003 cmp r1, r3
rate = SI5351_MULTISYNTH_MAX_FREQ;
54c: 81a05003 movhi r5, r3
/* multisync6-7 can only handle freqencies < 150MHz */
if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
550: 9a000052 bls 6a0 <si5351_msynth_round_rate+0x220>
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
554: e5960004 ldr r0, [r6, #4]
558: ebfffffe bl 0 <__clk_get_flags>
55c: e3100004 tst r0, #4
} else {
unsigned long rfrac, denom;
/* disable divby4 */
if (divby4) {
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
560: 030d5180 movweq r5, #53632 ; 0xd180
564: 034058f0 movteq r5, #2288 ; 0x8f0
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* multisync can set pll */
if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
568: 1a000035 bne 644 <si5351_msynth_round_rate+0x1c4>
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
56c: e5998000 ldr r8, [r9]
570: e1a01005 mov r1, r5
574: e1a00008 mov r0, r8
578: ebfffffe bl 0 <__aeabi_uidiv>
if (a < SI5351_MULTISYNTH_A_MIN)
57c: e3500005 cmp r0, #5
rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
580: e1a07000 mov r7, r0
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
584: 93a07006 movls r7, #6
divby4 = 0;
}
/* determine integer part of divider equation */
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
588: 8a000027 bhi 62c <si5351_msynth_round_rate+0x1ac>
else if (a > SI5351_MULTISYNTH_A_MAX)
a = SI5351_MULTISYNTH_A_MAX;
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
58c: e1a01005 mov r1, r5
590: e1a00008 mov r0, r8
594: ebfffffe bl 0 <__aeabi_uidivmod>
lltmp *= denom;
do_div(lltmp, rate);
598: e304b240 movw fp, #16960 ; 0x4240
59c: e340b00f movt fp, #15
rfrac = (unsigned long)lltmp;
b = 0;
5a0: e3a03000 mov r3, #0
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
5a4: e1a04005 mov r4, r5
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
5a8: e3a0a001 mov sl, #1
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
5ac: e0810b91 umull r0, r1, r1, fp
rfrac = (unsigned long)lltmp;
b = 0;
5b0: e58d3008 str r3, [sp, #8]
/* find best approximation for b/c = fVCO mod fOUT */
denom = 1000 * 1000;
lltmp = (*parent_rate) % rate;
lltmp *= denom;
do_div(lltmp, rate);
5b4: ebfffffe bl 0 <__do_div64>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
5b8: e2520000 subs r0, r2, #0
lltmp *= denom;
do_div(lltmp, rate);
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
5bc: e58da00c str sl, [sp, #12]
if (rfrac)
5c0: 1a000022 bne 650 <si5351_msynth_round_rate+0x1d0>
5c4: e1a03008 mov r3, r8
5c8: e1a05000 mov r5, r0
5cc: e1a0800a mov r8, sl
5d0: e1a04007 mov r4, r7
}
/* recalculate rate by fOUT = fIN / (a + b/c) */
lltmp = *parent_rate;
lltmp *= c;
do_div(lltmp, a * c + b);
5d4: e0810a93 umull r0, r1, r3, sl
5d8: ebfffffe bl 0 <__do_div64>
5dc: e1a04002 mov r4, r2
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
5e0: e1a05385 lsl r5, r5, #7
if (divby4) {
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
5e4: e5868018 str r8, [r6, #24]
hwdata->params.p2 = (128 * b) % c;
5e8: e1a01008 mov r1, r8
5ec: e1a00005 mov r0, r5
5f0: ebfffffe bl 0 <__aeabi_uidivmod>
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
5f4: e1a00005 mov r0, r5
hwdata->params.p3 = 1;
hwdata->params.p2 = 0;
hwdata->params.p1 = 0;
} else {
hwdata->params.p3 = c;
hwdata->params.p2 = (128 * b) % c;
5f8: e5861014 str r1, [r6, #20]
hwdata->params.p1 = 128 * a;
hwdata->params.p1 += (128 * b / c);
hwdata->params.p1 -= 512;
5fc: e1a01008 mov r1, r8
600: ebfffffe bl 0 <__aeabi_uidiv>
604: e2400c02 sub r0, r0, #512 ; 0x200
608: e0807387 add r7, r0, r7, lsl #7
60c: e5867010 str r7, [r6, #16]
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
*parent_rate, rate);
printk("parent_rate = %lu\n", *parent_rate);
610: e3000000 movw r0, #0
614: e5991000 ldr r1, [r9]
618: e3400000 movt r0, #0
61c: ebfffffe bl 0 <printk>
return rate;
}
620: e1a00004 mov r0, r4
624: e28dd014 add sp, sp, #20
628: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
/* determine integer part of divider equation */
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
62c: e5d63020 ldrb r3, [r6, #32]
630: e3530005 cmp r3, #5
634: 9a000015 bls 690 <si5351_msynth_round_rate+0x210>
a = SI5351_MULTISYNTH67_A_MAX;
638: e35700ff cmp r7, #255 ; 0xff
63c: 23a070fe movcs r7, #254 ; 0xfe
640: eaffffd1 b 58c <si5351_msynth_round_rate+0x10c>
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
rate = SI5351_MULTISYNTH_MIN_FREQ;
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
644: e3a0a001 mov sl, #1
if (divby4 == 0) {
lltmp = SI5351_PLL_VCO_MAX;
do_div(lltmp, rate);
a = (unsigned long)lltmp;
} else
a = 4;
648: e3a07004 mov r7, #4
64c: eaffffa7 b 4f0 <si5351_msynth_round_rate+0x70>
rfrac = (unsigned long)lltmp;
b = 0;
c = 1;
if (rfrac)
rational_best_approximation(rfrac, denom,
650: e30f3fff movw r3, #65535 ; 0xffff
654: e30f2ffe movw r2, #65534 ; 0xfffe
658: e28dc00c add ip, sp, #12
65c: e340300f movt r3, #15
660: e58dc004 str ip, [sp, #4]
664: e1a0100b mov r1, fp
668: e28dc008 add ip, sp, #8
66c: e340200f movt r2, #15
670: e58dc000 str ip, [sp]
674: ebfffffe bl 0 <rational_best_approximation>
678: e5993000 ldr r3, [r9]
67c: e59d800c ldr r8, [sp, #12]
680: e59d5008 ldr r5, [sp, #8]
684: e1a0a008 mov sl, r8
688: e0245897 mla r4, r7, r8, r5
68c: eaffffd0 b 5d4 <si5351_msynth_round_rate+0x154>
a = *parent_rate / rate;
if (a < SI5351_MULTISYNTH_A_MIN)
a = SI5351_MULTISYNTH_A_MIN;
if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
a = SI5351_MULTISYNTH67_A_MAX;
else if (a > SI5351_MULTISYNTH_A_MAX)
690: e3003708 movw r3, #1800 ; 0x708
a = SI5351_MULTISYNTH_A_MAX;
694: e1570003 cmp r7, r3
698: 21a07003 movcs r7, r3
69c: eaffffba b 58c <si5351_msynth_round_rate+0x10c>
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
6a0: e304323f movw r3, #16959 ; 0x423f
6a4: e340300f movt r3, #15
6a8: e1550003 cmp r5, r3
rate = SI5351_MULTISYNTH_MIN_FREQ;
6ac: 93045240 movwls r5, #16960 ; 0x4240
6b0: 9340500f movtls r5, #15
rate = SI5351_MULTISYNTH67_MAX_FREQ;
/* multisync frequency is 1MHz .. 160MHz */
if (rate > SI5351_MULTISYNTH_MAX_FREQ)
rate = SI5351_MULTISYNTH_MAX_FREQ;
if (rate < SI5351_MULTISYNTH_MIN_FREQ)
6b4: 9affff83 bls 4c8 <si5351_msynth_round_rate+0x48>
rate = SI5351_MULTISYNTH_MIN_FREQ;
divby4 = 0;
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
6b8: e30d3180 movw r3, #53632 ; 0xd180
6bc: e34038f0 movt r3, #2288 ; 0x8f0
6c0: e1550003 cmp r5, r3
6c4: 8affffa2 bhi 554 <si5351_msynth_round_rate+0xd4>
6c8: eaffff7e b 4c8 <si5351_msynth_round_rate+0x48>
000006cc <si5351_vxco_prepare>:
/*
* Si5351 vxco clock input (Si5351B only)
*/
static int si5351_vxco_prepare(struct clk_hw *hw)
{
6cc: e92d4010 push {r4, lr}
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
dev_warn(&hwdata->drvdata->client->dev, "VXCO currently unsupported\n");
6d0: e3001000 movw r1, #0
6d4: e590300c ldr r3, [r0, #12]
6d8: e3401000 movt r1, #0
6dc: e5930004 ldr r0, [r3, #4]
6e0: e2800020 add r0, r0, #32
6e4: ebfffffe bl 0 <dev_warn>
return 0;
}
6e8: e3a00000 mov r0, #0
6ec: e8bd8010 pop {r4, pc}
000006f0 <si5351_xtal_prepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
6f0: e3a03040 mov r3, #64 ; 0x40
6f4: e3a010bb mov r1, #187 ; 0xbb
/*
* Si5351 xtal clock input
*/
static int si5351_xtal_prepare(struct clk_hw *hw)
{
6f8: e92d4010 push {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
6fc: e1a02003 mov r2, r3
700: e5100014 ldr r0, [r0, #-20] ; 0xffffffec
704: ebfffffe bl 0 <regmap_update_bits>
struct si5351_driver_data *drvdata =
container_of(hw, struct si5351_driver_data, xtal);
si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
SI5351_XTAL_ENABLE, SI5351_XTAL_ENABLE);
return 0;
}
708: e3a00000 mov r0, #0
70c: e8bd8010 pop {r4, pc}
00000710 <si5351_xtal_unprepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
710: e5100014 ldr r0, [r0, #-20] ; 0xffffffec
714: e3a03000 mov r3, #0
718: e3a02040 mov r2, #64 ; 0x40
71c: e3a010bb mov r1, #187 ; 0xbb
720: eafffffe b 0 <regmap_update_bits>
00000724 <si5351_clkin_prepare>:
724: e3a03080 mov r3, #128 ; 0x80
728: e3a010bb mov r1, #187 ; 0xbb
/*
* Si5351 clkin clock input (Si5351C only)
*/
static int si5351_clkin_prepare(struct clk_hw *hw)
{
72c: e92d4010 push {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
730: e1a02003 mov r2, r3
734: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
738: ebfffffe bl 0 <regmap_update_bits>
struct si5351_driver_data *drvdata =
container_of(hw, struct si5351_driver_data, clkin);
si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
SI5351_CLKIN_ENABLE, SI5351_CLKIN_ENABLE);
return 0;
}
73c: e3a00000 mov r0, #0
740: e8bd8010 pop {r4, pc}
00000744 <si5351_clkin_unprepare>:
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
744: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
748: e3a03000 mov r3, #0
74c: e3a02080 mov r2, #128 ; 0x80
750: e3a010bb mov r1, #187 ; 0xbb
754: eafffffe b 0 <regmap_update_bits>
00000758 <si5351_clkin_recalc_rate>:
container_of(hw, struct si5351_driver_data, clkin);
unsigned long rate;
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
758: e3a03b1a mov r3, #26624 ; 0x6800
75c: e3403989 movt r3, #2441 ; 0x989
760: e1510003 cmp r1, r3
* The input frequency range of the PLL is 10Mhz to 40MHz.
* If CLKIN is >40MHz, the input divider must be used.
*/
static unsigned long si5351_clkin_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
764: e92d4010 push {r4, lr}
768: 83a030c0 movhi r3, #192 ; 0xc0
76c: e1a04001 mov r4, r1
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
770: 81a041a1 lsrhi r4, r1, #3
container_of(hw, struct si5351_driver_data, clkin);
unsigned long rate;
unsigned char idiv;
rate = parent_rate;
if (parent_rate > 160000000) {
774: 8a00000b bhi 7a8 <si5351_clkin_recalc_rate+0x50>
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
} else if (parent_rate > 80000000) {
778: e3a03b2d mov r3, #46080 ; 0xb400
77c: e34034c4 movt r3, #1220 ; 0x4c4
780: e1540003 cmp r4, r3
idiv = SI5351_CLKIN_DIV_4;
rate /= 4;
784: 81a04124 lsrhi r4, r4, #2
788: 83a03080 movhi r3, #128 ; 0x80
rate = parent_rate;
if (parent_rate > 160000000) {
idiv = SI5351_CLKIN_DIV_8;
rate /= 8;
} else if (parent_rate > 80000000) {
78c: 8a000005 bhi 7a8 <si5351_clkin_recalc_rate+0x50>
idiv = SI5351_CLKIN_DIV_4;
rate /= 4;
} else if (parent_rate > 40000000) {
790: e3a03c5a mov r3, #23040 ; 0x5a00
794: e3403262 movt r3, #610 ; 0x262
798: e1540003 cmp r4, r3
idiv = SI5351_CLKIN_DIV_2;
rate /= 2;
79c: 81a040a4 lsrhi r4, r4, #1
7a0: 83a03040 movhi r3, #64 ; 0x40
7a4: 93a03000 movls r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
7a8: e3a020c0 mov r2, #192 ; 0xc0
7ac: e3a0100f mov r1, #15
7b0: e5100028 ldr r0, [r0, #-40] ; 0xffffffd8
7b4: ebfffffe bl 0 <regmap_update_bits>
dev_dbg(&drvdata->client->dev, "%s - clkin div = %d, rate = %lu\n",
__func__, (1 << (idiv >> 6)), rate);
return rate;
}
7b8: e1a00004 mov r0, r4
7bc: e8bd8010 pop {r4, pc}
000007c0 <si5351_clkout_prepare>:
return 0;
}
static int si5351_clkout_prepare(struct clk_hw *hw)
{
7c0: e92d4010 push {r4, lr}
7c4: e1a04000 mov r4, r0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
7c8: e5d01020 ldrb r1, [r0, #32]
7cc: e3a03000 mov r3, #0
7d0: e590000c ldr r0, [r0, #12]
7d4: e3a02080 mov r2, #128 ; 0x80
7d8: e2811010 add r1, r1, #16
7dc: e5900008 ldr r0, [r0, #8]
7e0: e6ef1071 uxtb r1, r1
7e4: ebfffffe bl 0 <regmap_update_bits>
7e8: e5d42020 ldrb r2, [r4, #32]
7ec: e594000c ldr r0, [r4, #12]
7f0: e3a03001 mov r3, #1
7f4: e1a02213 lsl r2, r3, r2
7f8: e3a01003 mov r1, #3
7fc: e3a03000 mov r3, #0
800: e6ef2072 uxtb r2, r2
804: e5900008 ldr r0, [r0, #8]
808: ebfffffe bl 0 <regmap_update_bits>
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
SI5351_CLK_POWERDOWN, 0);
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), 0);
return 0;
}
80c: e3a00000 mov r0, #0
810: e8bd8010 pop {r4, pc}
00000814 <si5351_clkout_unprepare>:
static void si5351_clkout_unprepare(struct clk_hw *hw)
{
814: e92d4010 push {r4, lr}
818: e1a04000 mov r4, r0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
81c: e5d01020 ldrb r1, [r0, #32]
820: e3a03080 mov r3, #128 ; 0x80
824: e590000c ldr r0, [r0, #12]
828: e1a02003 mov r2, r3
82c: e2811010 add r1, r1, #16
830: e5900008 ldr r0, [r0, #8]
834: e6ef1071 uxtb r1, r1
838: ebfffffe bl 0 <regmap_update_bits>
83c: e5d41020 ldrb r1, [r4, #32]
840: e3a03001 mov r3, #1
844: e594200c ldr r2, [r4, #12]
848: e1a03113 lsl r3, r3, r1
84c: e3a01003 mov r1, #3
850: e6ef3073 uxtb r3, r3
854: e5920008 ldr r0, [r2, #8]
858: e1a02003 mov r2, r3
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN);
si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
(1 << hwdata->num), (1 << hwdata->num));
}
85c: e8bd4010 pop {r4, lr}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
860: eafffffe b 0 <regmap_update_bits>
00000864 <si5351_clkout_set_rate>:
return rate;
}
static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
864: e92d4010 push {r4, lr}
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
868: e1a0e0a2 lsr lr, r2, #1
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
86c: e0612002 rsb r2, r1, r2
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
870: e061c00e rsb ip, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
874: e3520000 cmp r2, #0
return rate;
}
static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
878: e1a04000 mov r4, r0
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
87c: b2622000 rsblt r2, r2, #0
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
880: e35c0000 cmp ip, #0
884: b26cc000 rsblt ip, ip, #0
container_of(hw, struct si5351_hw_data, hw);
unsigned long new_rate, new_err, err;
unsigned char rdiv;
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
888: e3a03000 mov r3, #0
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
88c: e152000c cmp r2, ip
890: 3a00000d bcc 8cc <si5351_clkout_set_rate+0x68>
break;
rdiv++;
894: e2833001 add r3, r3, #1
/* round to closed rdiv */
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
898: e1a0e0ae lsr lr, lr, #1
new_err = abs(new_rate - rate);
89c: e061200e rsb r2, r1, lr
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
break;
rdiv++;
8a0: e6ef3073 uxtb r3, r3
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
8a4: e3520000 cmp r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
8a8: e2430007 sub r0, r3, #7
rdiv = SI5351_OUTPUT_CLK_DIV_1;
new_rate = parent_rate;
err = abs(new_rate - rate);
do {
new_rate >>= 1;
new_err = abs(new_rate - rate);
8ac: b2622000 rsblt r2, r2, #0
if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
8b0: e16f0f10 clz r0, r0
8b4: e1a002a0 lsr r0, r0, #5
8b8: e152000c cmp r2, ip
8bc: 83800001 orrhi r0, r0, #1
8c0: e1a0c002 mov ip, r2
8c4: e3500000 cmp r0, #0
8c8: 0afffff1 beq 894 <si5351_clkout_set_rate+0x30>
rdiv++;
err = new_err;
} while (1);
/* write output divider */
switch (hwdata->num) {
8cc: e5d42020 ldrb r2, [r4, #32]
8d0: e3520006 cmp r2, #6
8d4: 0a000020 beq 95c <si5351_clkout_set_rate+0xf8>
8d8: e3520007 cmp r2, #7
8dc: 0a000016 beq 93c <si5351_clkout_set_rate+0xd8>
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
8e0: e3520005 cmp r2, #5
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
SI5351_OUTPUT_CLK_DIV_MASK,
rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
break;
default:
si5351_set_bits(hwdata->drvdata,
8e4: e594000c ldr r0, [r4, #12]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
8e8: d1a01182 lslle r1, r2, #3
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
8ec: c2821054 addgt r1, r2, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
8f0: d281102a addle r1, r1, #42 ; 0x2a
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
8f4: e1a03203 lsl r3, r3, #4
8f8: e20330f0 and r3, r3, #240 ; 0xf0
8fc: e5900008 ldr r0, [r0, #8]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
900: e6ef1071 uxtb r1, r1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
904: e3a02070 mov r2, #112 ; 0x70
908: e2811002 add r1, r1, #2
90c: e6ef1071 uxtb r1, r1
910: ebfffffe bl 0 <regmap_update_bits>
914: e5d41020 ldrb r1, [r4, #32]
918: e3a03000 mov r3, #0
91c: e594000c ldr r0, [r4, #12]
920: e3a02080 mov r2, #128 ; 0x80
924: e2811010 add r1, r1, #16
928: e5900008 ldr r0, [r0, #8]
92c: e6ef1071 uxtb r1, r1
930: ebfffffe bl 0 <regmap_update_bits>
"%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
parent_rate, rate);
return 0;
}
934: e3a00000 mov r0, #0
938: e8bd8010 pop {r4, pc}
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
93c: e594000c ldr r0, [r4, #12]
940: e1a03203 lsl r3, r3, #4
944: e20330f0 and r3, r3, #240 ; 0xf0
948: e3a02070 mov r2, #112 ; 0x70
94c: e3a0105c mov r1, #92 ; 0x5c
950: e5900008 ldr r0, [r0, #8]
954: ebfffffe bl 0 <regmap_update_bits>
958: eaffffed b 914 <si5351_clkout_set_rate+0xb0>
95c: e594000c ldr r0, [r4, #12]
960: e3a02007 mov r2, #7
964: e3a0105c mov r1, #92 ; 0x5c
968: e5900008 ldr r0, [r0, #8]
96c: ebfffffe bl 0 <regmap_update_bits>
970: eaffffe7 b 914 <si5351_clkout_set_rate+0xb0>
00000974 <si5351_read_parameters.isra.0>:
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
974: e92d40f0 push {r4, r5, r6, r7, lr}
978: e1a05002 mov r5, r2
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
97c: e242205a sub r2, r2, #90 ; 0x5a
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
980: e1a06000 mov r6, r0
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
984: e3520001 cmp r2, #1
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
}
static void si5351_read_parameters(struct si5351_driver_data *drvdata,
988: e24dd00c sub sp, sp, #12
98c: e1a00001 mov r0, r1
990: e1a04003 mov r4, r3
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
994: 8a00000d bhi 9d0 <si5351_read_parameters.isra.0+0x5c>
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
998: e1a0200d mov r2, sp
99c: e1a01005 mov r1, r5
9a0: ebfffffe bl 0 <regmap_read>
if (ret) {
9a4: e3500000 cmp r0, #0
9a8: 05dd3000 ldrbeq r3, [sp]
9ac: 1a000022 bne a3c <si5351_read_parameters.isra.0+0xc8>
switch (reg) {
case SI5351_CLK6_PARAMETERS:
case SI5351_CLK7_PARAMETERS:
buf[0] = si5351_reg_read(drvdata, reg);
params->p1 = buf[0];
9b0: e5843000 str r3, [r4]
params->p2 = 0;
params->p3 = 1;
9b4: e3a02000 mov r2, #0
9b8: e3a03001 mov r3, #1
9bc: e984000c stmib r4, {r2, r3}
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
9c0: e3a03001 mov r3, #1
9c4: e584300c str r3, [r4, #12]
}
9c8: e28dd00c add sp, sp, #12
9cc: e8bd80f0 pop {r4, r5, r6, r7, pc}
}
static inline int si5351_bulk_read(struct si5351_driver_data *drvdata,
u8 reg, u8 count, u8 *buf)
{
return regmap_bulk_read(drvdata->regmap, reg, buf, count);
9d0: e1a01005 mov r1, r5
9d4: e3a03008 mov r3, #8
9d8: e1a0200d mov r2, sp
9dc: ebfffffe bl 0 <regmap_bulk_read>
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
9e0: e5dd5005 ldrb r5, [sp, #5]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9e4: e5dd0003 ldrb r0, [sp, #3]
9e8: e5dde002 ldrb lr, [sp, #2]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
9ec: e205600f and r6, r5, #15
9f0: e5dd7006 ldrb r7, [sp, #6]
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
9f4: e20550f0 and r5, r5, #240 ; 0xf0
9f8: e5dd3000 ldrb r3, [sp]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
9fc: e20ee003 and lr, lr, #3
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a00: e5dd2001 ldrb r2, [sp, #1]
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a04: e5ddc004 ldrb ip, [sp, #4]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
a08: e5dd1007 ldrb r1, [sp, #7]
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a0c: e1823403 orr r3, r2, r3, lsl #8
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a10: e18c0400 orr r0, ip, r0, lsl #8
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a14: e1833605 orr r3, r3, r5, lsl #12
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
a18: e1811407 orr r1, r1, r7, lsl #8
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a1c: e180080e orr r0, r0, lr, lsl #16
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
a20: e1812806 orr r2, r1, r6, lsl #16
params->p2 = 0;
params->p3 = 1;
break;
default:
si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
a24: e5840000 str r0, [r4]
params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
a28: e984000c stmib r4, {r2, r3}
}
params->valid = 1;
a2c: e3a03001 mov r3, #1
a30: e584300c str r3, [r4, #12]
}
a34: e28dd00c add sp, sp, #12
a38: e8bd80f0 pop {r4, r5, r6, r7, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
a3c: e5960000 ldr r0, [r6]
a40: e3001000 movw r1, #0
a44: e1a02005 mov r2, r5
a48: e3401000 movt r1, #0
a4c: e2800020 add r0, r0, #32
a50: ebfffffe bl 0 <dev_err>
a54: e3a03000 mov r3, #0
a58: eaffffd4 b 9b0 <si5351_read_parameters.isra.0+0x3c>
00000a5c <si5351_msynth_recalc_rate>:
SI5351_MULTISYNTH_SRC_VCO1);
}
static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
a5c: e92d43f0 push {r4, r5, r6, r7, r8, r9, lr}
a60: e1a06000 mov r6, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
a64: e5d03020 ldrb r3, [r0, #32]
SI5351_MULTISYNTH_SRC_VCO1);
}
static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
a68: e24dd00c sub sp, sp, #12
a6c: e1a04001 mov r4, r1
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
a70: e3530005 cmp r3, #5
return SI5351_CLK6_PARAMETERS + (num - 6);
a74: c2833054 addgt r3, r3, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
a78: d1a05183 lslle r5, r3, #3
a7c: d285502a addle r5, r5, #42 ; 0x2a
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
a80: c6ef5073 uxtbgt r5, r3
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
a84: e590301c ldr r3, [r0, #28]
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
a88: d6ef5075 uxtble r5, r5
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
a8c: e3530000 cmp r3, #0
a90: 0a000013 beq ae4 <si5351_msynth_recalc_rate+0x88>
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
a94: e5963018 ldr r3, [r6, #24]
a98: e3530000 cmp r3, #0
a9c: 0a00000d beq ad8 <si5351_msynth_recalc_rate+0x7c>
/*
* multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
aa0: e5d63020 ldrb r3, [r6, #32]
/*
* multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
aa4: e1a08004 mov r8, r4
aa8: e3a09000 mov r9, #0
if (hwdata->num > 5) {
aac: e3530005 cmp r3, #5
ab0: 9a000012 bls b00 <si5351_msynth_recalc_rate+0xa4>
m = hwdata->params.p1;
ab4: e5964010 ldr r4, [r6, #16]
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
}
if (m == 0)
ab8: e3540000 cmp r4, #0
abc: 0a000005 beq ad8 <si5351_msynth_recalc_rate+0x7c>
return 0;
do_div(rate, m);
ac0: e1a00008 mov r0, r8
ac4: e1a01009 mov r1, r9
ac8: ebfffffe bl 0 <__do_div64>
acc: e1a00002 mov r0, r2
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
m, parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
ad0: e28dd00c add sp, sp, #12
ad4: e8bd83f0 pop {r4, r5, r6, r7, r8, r9, pc}
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
}
if (m == 0)
return 0;
ad8: e1a00004 mov r0, r4
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
m, parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
adc: e28dd00c add sp, sp, #12
ae0: e8bd83f0 pop {r4, r5, r6, r7, r8, r9, pc}
u8 reg = si5351_msynth_params_address(hwdata->num);
unsigned long long rate;
unsigned long m;
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
ae4: e590100c ldr r1, [r0, #12]
ae8: e2803010 add r3, r0, #16
aec: e1a02005 mov r2, r5
af0: e2810004 add r0, r1, #4
af4: e5911008 ldr r1, [r1, #8]
af8: ebffff9d bl 974 <si5351_read_parameters.isra.0>
afc: eaffffe4 b a94 <si5351_msynth_recalc_rate+0x38>
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
b00: e2855002 add r5, r5, #2
b04: e596700c ldr r7, [r6, #12]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
b08: e28d2004 add r2, sp, #4
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
b0c: e6ef5075 uxtb r5, r5
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
b10: e5970008 ldr r0, [r7, #8]
b14: e1a01005 mov r1, r5
b18: ebfffffe bl 0 <regmap_read>
if (ret) {
b1c: e3500000 cmp r0, #0
b20: 1a00000b bne b54 <si5351_msynth_recalc_rate+0xf8>
dev_err(&drvdata->client->dev,
"unable to read from reg%02x\n", reg);
return 0;
}
return (u8)val;
b24: e5dd3004 ldrb r3, [sp, #4]
* multisync6-7: fOUT = fIN / P1
*/
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
b28: e203300c and r3, r3, #12
b2c: e353000c cmp r3, #12
b30: 0a00000e beq b70 <si5351_msynth_recalc_rate+0x114>
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b34: e5962018 ldr r2, [r6, #24]
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b38: e5963010 ldr r3, [r6, #16]
b3c: e5960014 ldr r0, [r6, #20]
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b40: e1a08382 lsl r8, r2, #7
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b44: e2833c02 add r3, r3, #512 ; 0x200
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
} else {
rate *= 128 * hwdata->params.p3;
b48: e0898894 umull r8, r9, r4, r8
m = hwdata->params.p1 * hwdata->params.p3;
m += hwdata->params.p2;
m += 512 * hwdata->params.p3;
b4c: e0240392 mla r4, r2, r3, r0
b50: eaffffd8 b ab8 <si5351_msynth_recalc_rate+0x5c>
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
b54: e5970004 ldr r0, [r7, #4]
b58: e3001000 movw r1, #0
b5c: e1a02005 mov r2, r5
b60: e3401000 movt r1, #0
b64: e2800020 add r0, r0, #32
b68: ebfffffe bl 0 <dev_err>
b6c: eafffff0 b b34 <si5351_msynth_recalc_rate+0xd8>
rate = parent_rate;
if (hwdata->num > 5) {
m = hwdata->params.p1;
} else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
m = 4;
b70: e3a04004 mov r4, #4
b74: eaffffd1 b ac0 <si5351_msynth_recalc_rate+0x64>
00000b78 <si5351_pll_recalc_rate>:
SI5351_PLL_SRC_CLKIN);
}
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
b78: e92d41f0 push {r4, r5, r6, r7, r8, lr}
b7c: e1a04000 mov r4, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
b80: e5d02020 ldrb r2, [r0, #32]
SI5351_PLL_SRC_CLKIN);
}
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
b84: e1a05001 mov r5, r1
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
b88: e590301c ldr r3, [r0, #28]
static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
b8c: e3520000 cmp r2, #0
b90: 03a0201a moveq r2, #26
b94: 13a02022 movne r2, #34 ; 0x22
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
b98: e3530000 cmp r3, #0
b9c: 0a000013 beq bf0 <si5351_pll_recalc_rate+0x78>
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
ba0: e5943018 ldr r3, [r4, #24]
ba4: e3530000 cmp r3, #0
ba8: 0a00000e beq be8 <si5351_pll_recalc_rate+0x70>
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
bac: e5942010 ldr r2, [r4, #16]
rate += 512 * hwdata->params.p3;
bb0: e1a06483 lsl r6, r3, #9
rate += hwdata->params.p2;
rate *= parent_rate;
bb4: e5941014 ldr r1, [r4, #20]
do_div(rate, 128 * hwdata->params.p3);
bb8: e1a04383 lsl r4, r3, #7
if (hwdata->params.p3 == 0)
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
rate += 512 * hwdata->params.p3;
bbc: e3a07000 mov r7, #0
if (hwdata->params.p3 == 0)
return parent_rate;
/* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
rate = hwdata->params.p1 * hwdata->params.p3;
bc0: e0030392 mul r3, r2, r3
rate += 512 * hwdata->params.p3;
bc4: e0966003 adds r6, r6, r3
bc8: e2a77000 adc r7, r7, #0
rate += hwdata->params.p2;
rate *= parent_rate;
bcc: e0966001 adds r6, r6, r1
bd0: e2a77000 adc r7, r7, #0
bd4: e0810596 umull r0, r1, r6, r5
bd8: e0211795 mla r1, r5, r7, r1
do_div(rate, 128 * hwdata->params.p3);
bdc: ebfffffe bl 0 <__do_div64>
be0: e1a00002 mov r0, r2
"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, (unsigned long)rate);
return (unsigned long)rate;
be4: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
if (hwdata->params.p3 == 0)
return parent_rate;
be8: e1a00005 mov r0, r5
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, (unsigned long)rate);
return (unsigned long)rate;
}
bec: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
unsigned long long rate;
if (!hwdata->params.valid)
si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
bf0: e590100c ldr r1, [r0, #12]
bf4: e2803010 add r3, r0, #16
bf8: e2810004 add r0, r1, #4
bfc: e5911008 ldr r1, [r1, #8]
c00: ebffff5b bl 974 <si5351_read_parameters.isra.0>
c04: eaffffe5 b ba0 <si5351_pll_recalc_rate+0x28>
00000c08 <si5351_write_parameters.isra.1>:
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
c08: e92d41f0 push {r4, r5, r6, r7, r8, lr}
c0c: e1a06002 mov r6, r2
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
c10: e242205a sub r2, r2, #90 ; 0x5a
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
c14: e24dd010 sub sp, sp, #16
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
c18: e3520001 cmp r2, #1
params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
}
params->valid = 1;
}
static void si5351_write_parameters(struct si5351_driver_data *drvdata,
c1c: e1a07001 mov r7, r1
c20: e1a05003 mov r5, r3
u8 reg, struct si5351_parameters *params)
{
u8 buf[SI5351_PARAMETERS_LENGTH];
switch (reg) {
c24: 9a000025 bls cc0 <si5351_write_parameters.isra.1+0xb8>
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
c28: e2864002 add r4, r6, #2
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c2c: e5933008 ldr r3, [r3, #8]
c30: e1a08000 mov r8, r0
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c34: e28d2004 add r2, sp, #4
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
c38: e6ef4074 uxtb r4, r4
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c3c: e5910000 ldr r0, [r1]
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c40: e7e7c453 ubfx ip, r3, #8, #8
buf[1] = params->p3 & 0xff;
c44: e5cd3009 strb r3, [sp, #9]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c48: e1a01004 mov r1, r4
case SI5351_CLK7_PARAMETERS:
buf[0] = params->p1 & 0xff;
si5351_reg_write(drvdata, reg, buf[0]);
break;
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
c4c: e5cdc008 strb ip, [sp, #8]
static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
{
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
c50: ebfffffe bl 0 <regmap_read>
if (ret) {
c54: e3500000 cmp r0, #0
c58: 059d4004 ldreq r4, [sp, #4]
c5c: 020480fc andeq r8, r4, #252 ; 0xfc
c60: 1a00001c bne cd8 <si5351_write_parameters.isra.1+0xd0>
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c64: e5952008 ldr r2, [r5, #8]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c68: e3a03008 mov r3, #8
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
c6c: e595e004 ldr lr, [r5, #4]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c70: e1a01006 mov r1, r6
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c74: e595c000 ldr ip, [r5]
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c78: e202480f and r4, r2, #983040 ; 0xf0000
c7c: e7e3285e ubfx r2, lr, #16, #4
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c80: e5970000 ldr r0, [r7]
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c84: e1822624 orr r2, r2, r4, lsr #12
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c88: e7e1485c ubfx r4, ip, #16, #2
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
c8c: e5cd200d strb r2, [sp, #13]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
c90: e08d2003 add r2, sp, r3
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
c94: e5cde00f strb lr, [sp, #15]
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
c98: e1884004 orr r4, r8, r4
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
c9c: e7e7e45e ubfx lr, lr, #8, #8
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
buf[4] = params->p1 & 0xff;
ca0: e5cdc00c strb ip, [sp, #12]
buf[5] = ((params->p3 & 0xf0000) >> 12) |
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
ca4: e5cde00e strb lr, [sp, #14]
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
ca8: e7e7c45c ubfx ip, ip, #8, #8
default:
buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
buf[1] = params->p3 & 0xff;
/* save rdiv and divby4 */
buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
cac: e5cd400a strb r4, [sp, #10]
buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
cb0: e5cdc00b strb ip, [sp, #11]
}
static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
u8 reg, u8 count, const u8 *buf)
{
return regmap_raw_write(drvdata->regmap, reg, buf, count);
cb4: ebfffffe bl 0 <regmap_raw_write>
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
}
}
cb8: e28dd010 add sp, sp, #16
cbc: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
}
static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
u8 reg, u8 val)
{
return regmap_write(drvdata->regmap, reg, val);
cc0: e5d32000 ldrb r2, [r3]
cc4: e1a01006 mov r1, r6
cc8: e5970000 ldr r0, [r7]
ccc: ebfffffe bl 0 <regmap_write>
((params->p2 & 0xf0000) >> 16);
buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
buf[7] = params->p2 & 0xff;
si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
}
}
cd0: e28dd010 add sp, sp, #16
cd4: e8bd81f0 pop {r4, r5, r6, r7, r8, pc}
u32 val;
int ret;
ret = regmap_read(drvdata->regmap, reg, &val);
if (ret) {
dev_err(&drvdata->client->dev,
cd8: e5980000 ldr r0, [r8]
cdc: e3001000 movw r1, #0
ce0: e1a02004 mov r2, r4
ce4: e3401000 movt r1, #0
ce8: e2800020 add r0, r0, #32
cec: e3a08000 mov r8, #0
cf0: ebfffffe bl 0 <dev_err>
cf4: eaffffda b c64 <si5351_write_parameters.isra.1+0x5c>
00000cf8 <si5351_pll_set_rate>:
return rate;
}
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
cf8: e92d4010 push {r4, lr}
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
cfc: e2803010 add r3, r0, #16
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
d00: e5d02020 ldrb r2, [r0, #32]
return rate;
}
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
d04: e1a04000 mov r4, r0
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d08: e590000c ldr r0, [r0, #12]
static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
d0c: e3520000 cmp r2, #0
SI5351_PLLB_PARAMETERS;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d10: e2801008 add r1, r0, #8
d14: e2800004 add r0, r0, #4
d18: 13a02022 movne r2, #34 ; 0x22
d1c: 03a0201a moveq r2, #26
d20: ebffffb8 bl c08 <si5351_write_parameters.isra.1>
/* plla/pllb ctrl is in clk6/clk7 ctrl registers */
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
d24: e5940014 ldr r0, [r4, #20]
d28: e5d41020 ldrb r1, [r4, #32]
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
d2c: e3a02040 mov r2, #64 ; 0x40
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
/* plla/pllb ctrl is in clk6/clk7 ctrl registers */
si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
d30: e594300c ldr r3, [r4, #12]
d34: e3500000 cmp r0, #0
d38: e2811016 add r1, r1, #22
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
d3c: e5930008 ldr r0, [r3, #8]
d40: e6ef1071 uxtb r1, r1
d44: 01a03002 moveq r3, r2
d48: 13a03000 movne r3, #0
d4c: ebfffffe bl 0 <regmap_update_bits>
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
parent_rate, rate);
return 0;
}
d50: e3a00000 mov r0, #0
d54: e8bd8010 pop {r4, pc}
00000d58 <si5351_msynth_set_rate>:
return rate;
}
static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
d58: e92d4070 push {r4, r5, r6, lr}
d5c: e1a05000 mov r5, r0
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
d60: e5d03020 ldrb r3, [r0, #32]
return rate;
}
static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
d64: e1a06001 mov r6, r1
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d68: e590000c ldr r0, [r0, #12]
return regmap_update_bits(drvdata->regmap, reg, mask, val);
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
d6c: e3530005 cmp r3, #5
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d70: d1a04183 lslle r4, r3, #3
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
d74: c2833054 addgt r3, r3, #84 ; 0x54
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d78: d284402a addle r4, r4, #42 ; 0x2a
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d7c: e2801008 add r1, r0, #8
}
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
d80: c6ef4073 uxtbgt r4, r3
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d84: e2800004 add r0, r0, #4
static inline u8 si5351_msynth_params_address(int num)
{
if (num > 5)
return SI5351_CLK6_PARAMETERS + (num - 6);
return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
d88: d6ef4074 uxtble r4, r4
container_of(hw, struct si5351_hw_data, hw);
u8 reg = si5351_msynth_params_address(hwdata->num);
int divby4 = 0;
/* write multisynth parameters */
si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
d8c: e2853010 add r3, r5, #16
d90: e1a02004 mov r2, r4
d94: ebffff9b bl c08 <si5351_write_parameters.isra.1>
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
d98: e30d3180 movw r3, #53632 ; 0xd180
d9c: e34038f0 movt r3, #2288 ; 0x8f0
da0: e1560003 cmp r6, r3
da4: 9a000007 bls dc8 <si5351_msynth_set_rate+0x70>
divby4 = 1;
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
da8: e5d53020 ldrb r3, [r5, #32]
dac: e3530005 cmp r3, #5
db0: 8a000019 bhi e1c <si5351_msynth_set_rate+0xc4>
si5351_set_bits(hwdata->drvdata, reg + 2,
db4: e2844002 add r4, r4, #2
db8: e595200c ldr r2, [r5, #12]
dbc: e3a0300c mov r3, #12
dc0: e6ef1074 uxtb r1, r4
dc4: ea000006 b de4 <si5351_msynth_set_rate+0x8c>
if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
divby4 = 1;
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
dc8: e5d53020 ldrb r3, [r5, #32]
dcc: e3530005 cmp r3, #5
dd0: 8a000011 bhi e1c <si5351_msynth_set_rate+0xc4>
si5351_set_bits(hwdata->drvdata, reg + 2,
dd4: e2844002 add r4, r4, #2
dd8: e595200c ldr r2, [r5, #12]
ddc: e3a03000 mov r3, #0
de0: e6ef1074 uxtb r1, r4
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
de4: e5920008 ldr r0, [r2, #8]
de8: e3a0200c mov r2, #12
dec: ebfffffe bl 0 <regmap_update_bits>
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
si5351_set_bits(hwdata->drvdata, reg + 2,
SI5351_OUTPUT_CLK_DIVBY4,
(divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
df0: e5950014 ldr r0, [r5, #20]
df4: e5d51020 ldrb r1, [r5, #32]
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
df8: e3a02040 mov r2, #64 ; 0x40
/* enable/disable integer mode and divby4 on multisynth0-5 */
if (hwdata->num < 6) {
si5351_set_bits(hwdata->drvdata, reg + 2,
SI5351_OUTPUT_CLK_DIVBY4,
(divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
dfc: e595300c ldr r3, [r5, #12]
e00: e3500000 cmp r0, #0
e04: e2811010 add r1, r1, #16
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
e08: e5930008 ldr r0, [r3, #8]
e0c: e6ef1071 uxtb r1, r1
e10: 01a03002 moveq r3, r2
e14: 13a03000 movne r3, #0
e18: ebfffffe bl 0 <regmap_update_bits>
__func__, __clk_get_name(hwdata->hw.clk),
hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
divby4, parent_rate, rate);
return 0;
}
e1c: e3a00000 mov r0, #0
e20: e8bd8070 pop {r4, r5, r6, pc}
00000e24 <si5351_regmap_is_writeable>:
}
static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
{
/* reserved registers */
if (reg >= 4 && reg <= 8)
e24: e2413004 sub r3, r1, #4
e28: e3530004 cmp r3, #4
e2c: 9a00000c bls e64 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 10 && reg <= 14)
e30: e241300a sub r3, r1, #10
e34: e3530004 cmp r3, #4
e38: 9a000009 bls e64 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 173 && reg <= 176)
e3c: e24130ad sub r3, r1, #173 ; 0xad
e40: e3530003 cmp r3, #3
e44: 9a000006 bls e64 <si5351_regmap_is_writeable+0x40>
return false;
if (reg >= 178 && reg <= 182)
return false;
/* read-only */
if (reg == SI5351_DEVICE_STATUS)
e48: e24100b2 sub r0, r1, #178 ; 0xb2
e4c: e3510000 cmp r1, #0
e50: 13500004 cmpne r0, #4
e54: 93a01001 movls r1, #1
e58: 83a01000 movhi r1, #0
e5c: e2210001 eor r0, r1, #1
e60: e12fff1e bx lr
static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
{
/* reserved registers */
if (reg >= 4 && reg <= 8)
return false;
e64: e3a00000 mov r0, #0
return false;
/* read-only */
if (reg == SI5351_DEVICE_STATUS)
return false;
return true;
}
e68: e12fff1e bx lr
00000e6c <_si5351_pll_reparent.isra.4>:
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e6c: e3520000 cmp r2, #0
*
* a + b/c = (MSNx_P1 + MSNx_P2/MSNx_P3 + 512)/128
* = (MSNx_P1*MSNx_P3 + MSNx_P2 + 512*MSNx_P3)/(128*MSNx_P3)
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
e70: e92d4010 push {r4, lr}
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e74: 0a00000f beq eb8 <_si5351_pll_reparent.isra.4+0x4c>
if (parent == SI5351_PLL_SRC_DEFAULT)
e78: e3530000 cmp r3, #0
e7c: 0a00000b beq eb0 <_si5351_pll_reparent.isra.4+0x44>
return 0;
if (num > 2)
e80: e3520002 cmp r2, #2
e84: ca000015 bgt ee0 <_si5351_pll_reparent.isra.4+0x74>
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
e88: e5900000 ldr r0, [r0]
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
e8c: e3a02008 mov r2, #8
return 0;
if (num > 2)
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
e90: e3500004 cmp r0, #4
e94: 0a00000d beq ed0 <_si5351_pll_reparent.isra.4+0x64>
e98: e3530001 cmp r3, #1
e9c: 1a00000f bne ee0 <_si5351_pll_reparent.isra.4+0x74>
ea0: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
ea4: e5910000 ldr r0, [r1]
ea8: e3a0100f mov r1, #15
eac: ebfffffe bl 0 <regmap_update_bits>
parent != SI5351_PLL_SRC_XTAL)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
(parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
return 0;
eb0: e3a00000 mov r0, #0
eb4: e8bd8010 pop {r4, pc}
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
if (parent == SI5351_PLL_SRC_DEFAULT)
eb8: e3530000 cmp r3, #0
*
*/
static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_pll_src parent)
{
u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
ebc: 13a02004 movne r2, #4
if (parent == SI5351_PLL_SRC_DEFAULT)
ec0: 0afffffa beq eb0 <_si5351_pll_reparent.isra.4+0x44>
return 0;
if (num > 2)
return -EINVAL;
if (drvdata->variant != SI5351_VARIANT_C &&
ec4: e5900000 ldr r0, [r0]
ec8: e3500004 cmp r0, #4
ecc: 1afffff1 bne e98 <_si5351_pll_reparent.isra.4+0x2c>
parent != SI5351_PLL_SRC_XTAL)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
ed0: e3530001 cmp r3, #1
ed4: 11a03002 movne r3, r2
ed8: 03a03000 moveq r3, #0
edc: eafffff0 b ea4 <_si5351_pll_reparent.isra.4+0x38>
if (parent == SI5351_PLL_SRC_DEFAULT)
return 0;
if (num > 2)
return -EINVAL;
ee0: e3e00015 mvn r0, #21
ee4: e8bd8010 pop {r4, pc}
00000ee8 <si5351_pll_set_parent>:
static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
ee8: e590c00c ldr ip, [r0, #12]
eec: e59c3000 ldr r3, [ip]
ef0: e3530004 cmp r3, #4
ef4: 0a000006 beq f14 <si5351_pll_set_parent+0x2c>
ef8: e3510000 cmp r1, #0
return -EPERM;
if (index > 1)
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
efc: 05d02020 ldrbeq r2, [r0, #32]
f00: 03a03001 moveq r3, #1
static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
f04: 1a00000d bne f40 <si5351_pll_set_parent+0x58>
return -EPERM;
if (index > 1)
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
f08: e28c1008 add r1, ip, #8
f0c: e1a0000c mov r0, ip
f10: eaffffd5 b e6c <_si5351_pll_reparent.isra.4>
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
if (index > 1)
f14: e3510001 cmp r1, #1
f18: 8a000006 bhi f38 <si5351_pll_set_parent+0x50>
return -EINVAL;
return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
f1c: e3510000 cmp r1, #0
f20: e5d02020 ldrb r2, [r0, #32]
f24: e28c1008 add r1, ip, #8
f28: e1a0000c mov r0, ip
f2c: 03a03001 moveq r3, #1
f30: 13a03002 movne r3, #2
f34: eaffffcc b e6c <_si5351_pll_reparent.isra.4>
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
if (index > 1)
return -EINVAL;
f38: e3e00015 mvn r0, #21
f3c: e12fff1e bx lr
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
index > 0)
return -EPERM;
f40: e3e00000 mvn r0, #0
f44: e12fff1e bx lr
00000f48 <_si5351_clkout_reparent.isra.7>:
static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
f48: e3520008 cmp r2, #8
};
/*
* Si5351 clkout divider
*/
static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
f4c: e92d4010 push {r4, lr}
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
f50: ca000016 bgt fb0 <_si5351_clkout_reparent.isra.7+0x68>
return -EINVAL;
switch (parent) {
f54: e2433001 sub r3, r3, #1
f58: e3530003 cmp r3, #3
f5c: 979ff103 ldrls pc, [pc, r3, lsl #2]
f60: ea000016 b fc0 <_si5351_clkout_reparent.isra.7+0x78>
f64: 00000fb8 .word 0x00000fb8
f68: 00000f94 .word 0x00000f94
f6c: 00000f74 .word 0x00000f74
f70: 00000fa4 .word 0x00000fa4
f74: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
f78: e282c010 add ip, r2, #16
f7c: e5910000 ldr r0, [r1]
f80: e3a0200c mov r2, #12
f84: e6ef107c uxtb r1, ip
f88: ebfffffe bl 0 <regmap_update_bits>
return 0;
}
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
SI5351_CLK_INPUT_MASK, val);
return 0;
f8c: e3a00000 mov r0, #0
f90: e8bd8010 pop {r4, pc}
case SI5351_CLKOUT_SRC_MSYNTH_N:
val = SI5351_CLK_INPUT_MULTISYNTH_N;
break;
case SI5351_CLKOUT_SRC_MSYNTH_0_4:
/* clk0/clk4 can only connect to its own multisync */
if (num == 0 || num == 4)
f94: e3d23004 bics r3, r2, #4
f98: 03a0300c moveq r3, #12
f9c: 13a03008 movne r3, #8
fa0: eafffff4 b f78 <_si5351_clkout_reparent.isra.7+0x30>
break;
case SI5351_CLKOUT_SRC_XTAL:
val = SI5351_CLK_INPUT_XTAL;
break;
case SI5351_CLKOUT_SRC_CLKIN:
if (drvdata->variant != SI5351_VARIANT_C)
fa4: e5903000 ldr r3, [r0]
fa8: e3530004 cmp r3, #4
fac: 0afffff1 beq f78 <_si5351_clkout_reparent.isra.7+0x30>
int num, enum si5351_clkout_src parent)
{
u8 val;
if (num > 8)
return -EINVAL;
fb0: e3e00015 mvn r0, #21
}
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
SI5351_CLK_INPUT_MASK, val);
return 0;
}
fb4: e8bd8010 pop {r4, pc}
u8 val;
if (num > 8)
return -EINVAL;
switch (parent) {
fb8: e3a0300c mov r3, #12
fbc: eaffffed b f78 <_si5351_clkout_reparent.isra.7+0x30>
return -EINVAL;
val = SI5351_CLK_INPUT_CLKIN;
break;
default:
return 0;
fc0: e3a00000 mov r0, #0
fc4: e8bd8010 pop {r4, pc}
00000fc8 <si5351_clkout_set_parent>:
return index;
}
static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
{
fc8: e3510003 cmp r1, #3
fcc: e1a02000 mov r2, r0
case 3:
parent = SI5351_CLKOUT_SRC_CLKIN;
break;
}
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
fd0: e590000c ldr r0, [r0, #12]
fd4: 93003000 movwls r3, #0
return index;
}
static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
{
fd8: 83a03000 movhi r3, #0
fdc: 93403000 movtls r3, #0
fe0: 90833101 addls r3, r3, r1, lsl #2
case 3:
parent = SI5351_CLKOUT_SRC_CLKIN;
break;
}
return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
fe4: e5d22020 ldrb r2, [r2, #32]
fe8: e2801008 add r1, r0, #8
fec: 95933024 ldrls r3, [r3, #36] ; 0x24
ff0: eaffffd4 b f48 <_si5351_clkout_reparent.isra.7>
00000ff4 <si5351_i2c_probe>:
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
ff4: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
{
struct device_node *child, *np = client->dev.of_node;
struct si5351_platform_data *pdata;
struct property *prop;
const __be32 *p;
int num = 0;
ff8: e3a06000 mov r6, #0
MODULE_DEVICE_TABLE(of, si5351_dt_ids);
static int si5351_dt_parse(struct i2c_client *client,
enum si5351_variant variant)
{
struct device_node *child, *np = client->dev.of_node;
ffc: e5905204 ldr r5, [r0, #516] ; 0x204
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
1000: e24dd04c sub sp, sp, #76 ; 0x4c
enum si5351_variant variant = (enum si5351_variant)id->driver_data;
1004: e5917014 ldr r7, [r1, #20]
struct property *prop;
const __be32 *p;
int num = 0;
u32 val;
if (np == NULL)
1008: e1550006 cmp r5, r6
}
#endif /* CONFIG_OF */
static int si5351_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
100c: e58d0004 str r0, [sp, #4]
{
struct device_node *child, *np = client->dev.of_node;
struct si5351_platform_data *pdata;
struct property *prop;
const __be32 *p;
int num = 0;
1010: e58d6024 str r6, [sp, #36] ; 0x24
u32 val;
if (np == NULL)
1014: 0a000041 beq 1120 <si5351_i2c_probe+0x12c>
return 0;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1018: e280b020 add fp, r0, #32
va_list ap);
extern __printf(3, 4)
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
101c: e30820d0 movw r2, #32976 ; 0x80d0
1020: e3a010c8 mov r1, #200 ; 0xc8
1024: e1a0000b mov r0, fp
1028: ebfffffe bl 0 <devm_kmalloc>
if (!pdata)
102c: e2508000 subs r8, r0, #0
1030: 0a000341 beq 1d3c <si5351_i2c_probe+0xd48>
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
1034: e28d3024 add r3, sp, #36 ; 0x24
1038: e3001000 movw r1, #0
103c: e3401000 movt r1, #0
1040: e1a02006 mov r2, r6
1044: e1a00005 mov r0, r5
1048: e1a09003 mov r9, r3
104c: e58d3000 str r3, [sp]
1050: ebfffffe bl 0 <of_find_property>
1054: e1a01006 mov r1, r6
1058: e1a02009 mov r2, r9
105c: e1a04000 mov r4, r0
1060: ebfffffe bl 0 <of_prop_next_u32>
1064: e2501000 subs r1, r0, #0
1068: 0a000232 beq 1938 <si5351_i2c_probe+0x944>
if (num >= 2) {
106c: e59d2024 ldr r2, [sp, #36] ; 0x24
1070: e3520001 cmp r2, #1
1074: d28d6034 addle r6, sp, #52 ; 0x34
return -EINVAL;
}
switch (val) {
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
1078: d3a09001 movle r9, #1
dev_err(&client->dev,
"invalid parent %d for pll %d\n",
val, num);
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
107c: d3a0a002 movle sl, #2
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
if (num >= 2) {
1080: ca000015 bgt 10dc <si5351_i2c_probe+0xe8>
dev_err(&client->dev,
"invalid pll %d on pll-source prop\n", num);
return -EINVAL;
}
p = of_prop_next_u32(prop, p, &val);
1084: e1a02006 mov r2, r6
1088: e1a00004 mov r0, r4
108c: ebfffffe bl 0 <of_prop_next_u32>
if (!p) {
1090: e2501000 subs r1, r0, #0
1094: 0a0002df beq 1c18 <si5351_i2c_probe+0xc24>
dev_err(&client->dev,
"missing pll-source for pll %d\n", num);
return -EINVAL;
}
switch (val) {
1098: e59d2034 ldr r2, [sp, #52] ; 0x34
109c: e3520000 cmp r2, #0
10a0: 0a00001b beq 1114 <si5351_i2c_probe+0x120>
10a4: e3520001 cmp r2, #1
10a8: 1a000011 bne 10f4 <si5351_i2c_probe+0x100>
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
break;
case 1:
if (variant != SI5351_VARIANT_C) {
10ac: e3570004 cmp r7, #4
10b0: 1a00000f bne 10f4 <si5351_i2c_probe+0x100>
dev_err(&client->dev,
"invalid parent %d for pll %d\n",
val, num);
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
10b4: e59d3024 ldr r3, [sp, #36] ; 0x24
10b8: e788a103 str sl, [r8, r3, lsl #2]
/*
* property silabs,pll-source : <num src>, [<..>]
* allow to selectively set pll source
*/
of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
10bc: e59d2000 ldr r2, [sp]
10c0: e1a00004 mov r0, r4
10c4: ebfffffe bl 0 <of_prop_next_u32>
10c8: e2501000 subs r1, r0, #0
10cc: 0a000219 beq 1938 <si5351_i2c_probe+0x944>
if (num >= 2) {
10d0: e59d2024 ldr r2, [sp, #36] ; 0x24
10d4: e3520001 cmp r2, #1
10d8: daffffe9 ble 1084 <si5351_i2c_probe+0x90>
dev_err(&client->dev,
10dc: e3001000 movw r1, #0
10e0: e1a0000b mov r0, fp
10e4: e3401000 movt r1, #0
10e8: ebfffffe bl 0 <dev_err>
"invalid pll %d on pll-source prop\n", num);
return -EINVAL;
10ec: e3e00015 mvn r0, #21
10f0: ea000005 b 110c <si5351_i2c_probe+0x118>
return -EINVAL;
}
pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
break;
default:
dev_err(&client->dev,
10f4: e3001000 movw r1, #0
10f8: e1a0000b mov r0, fp
10fc: e3401000 movt r1, #0
1100: e59d3024 ldr r3, [sp, #36] ; 0x24
1104: ebfffffe bl 0 <dev_err>
"invalid parent %d for pll %d\n", val, num);
return -EINVAL;
1108: e3e00015 mvn r0, #21
if (!IS_ERR(drvdata->pxtal))
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_disable_unprepare(drvdata->pclkin);
return ret;
}
110c: e28dd04c add sp, sp, #76 ; 0x4c
1110: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
return -EINVAL;
}
switch (val) {
case 0:
pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
1114: e59d3024 ldr r3, [sp, #36] ; 0x24
1118: e7889103 str r9, [r8, r3, lsl #2]
111c: eaffffe6 b 10bc <si5351_i2c_probe+0xc8>
1120: e59d3004 ldr r3, [sp, #4]
1124: e59380a0 ldr r8, [r3, #160] ; 0xa0
ret = si5351_dt_parse(client, variant);
if (ret)
return ret;
pdata = client->dev.platform_data;
if (!pdata)
1128: e3580000 cmp r8, #0
112c: 0a000304 beq 1d44 <si5351_i2c_probe+0xd50>
1130: e283b020 add fp, r3, #32
1134: e30820d0 movw r2, #32976 ; 0x80d0
1138: e3a0108c mov r1, #140 ; 0x8c
113c: e1a0000b mov r0, fp
1140: ebfffffe bl 0 <devm_kmalloc>
return -EINVAL;
drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
if (drvdata == NULL) {
1144: e2504000 subs r4, r0, #0
1148: 0a00030d beq 1d84 <si5351_i2c_probe+0xd90>
return dev->driver_data;
}
static inline void dev_set_drvdata(struct device *dev, void *data)
{
dev->driver_data = data;
114c: e59d3004 ldr r3, [sp, #4]
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1150: e3001000 movw r1, #0
1154: e3401000 movt r1, #0
1158: e1a0000b mov r0, fp
115c: e58340a4 str r4, [r3, #164] ; 0xa4
dev_err(&client->dev, "unable to allocate driver data\n");
return -ENOMEM;
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
1160: e5843004 str r3, [r4, #4]
drvdata->variant = variant;
1164: e5847000 str r7, [r4]
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1168: ebfffffe bl 0 <devm_clk_get>
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
116c: e3001000 movw r1, #0
1170: e3401000 movt r1, #0
}
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
1174: e5840014 str r0, [r4, #20]
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
1178: e1a0000b mov r0, fp
117c: ebfffffe bl 0 <devm_clk_get>
if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
1180: e5945014 ldr r5, [r4, #20]
1184: e3e03f81 mvn r3, #516 ; 0x204
1188: e1550003 cmp r5, r3
i2c_set_clientdata(client, drvdata);
drvdata->client = client;
drvdata->variant = variant;
drvdata->pxtal = devm_clk_get(&client->dev, "xtal");
drvdata->pclkin = devm_clk_get(&client->dev, "clkin");
118c: e5840028 str r0, [r4, #40] ; 0x28
if (PTR_ERR(drvdata->pxtal) == -EPROBE_DEFER ||
1190: 0a0001d6 beq 18f0 <si5351_i2c_probe+0x8fc>
1194: e1500003 cmp r0, r3
1198: 0affffdb beq 110c <si5351_i2c_probe+0x118>
/*
* Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
* VARIANT_C can have CLKIN instead.
*/
if (IS_ERR(drvdata->pxtal) &&
119c: e3750a01 cmn r5, #4096 ; 0x1000
11a0: 8a0001b9 bhi 188c <si5351_i2c_probe+0x898>
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
dev_err(&client->dev, "missing parent clock\n");
return -EINVAL;
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
11a4: e59f1c60 ldr r1, [pc, #3168] ; 1e0c <si5351_i2c_probe+0xe18>
11a8: e59d0004 ldr r0, [sp, #4]
11ac: ebfffffe bl 0 <devm_regmap_init_i2c>
if (IS_ERR(drvdata->regmap)) {
11b0: e3700a01 cmn r0, #4096 ; 0x1000
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
dev_err(&client->dev, "missing parent clock\n");
return -EINVAL;
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
11b4: e5840008 str r0, [r4, #8]
if (IS_ERR(drvdata->regmap)) {
11b8: 8a0001be bhi 18b8 <si5351_i2c_probe+0x8c4>
}
static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
u8 reg, u8 val)
{
return regmap_write(drvdata->regmap, reg, val);
11bc: e3a020f0 mov r2, #240 ; 0xf0
11c0: e3a01002 mov r1, #2
11c4: ebfffffe bl 0 <regmap_write>
}
/* Disable interrupts */
si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
/* Ensure pll select is on XTAL for Si5351A/B */
if (drvdata->variant != SI5351_VARIANT_C)
11c8: e5943000 ldr r3, [r4]
11cc: e3530004 cmp r3, #4
11d0: 0a000004 beq 11e8 <si5351_i2c_probe+0x1f4>
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
11d4: e3a03000 mov r3, #0
11d8: e3a0200c mov r2, #12
11dc: e3a0100f mov r1, #15
11e0: e5940008 ldr r0, [r4, #8]
11e4: ebfffffe bl 0 <regmap_update_bits>
11e8: e284a008 add sl, r4, #8
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
11ec: e5983000 ldr r3, [r8]
11f0: e3a02000 mov r2, #0
11f4: e1a00004 mov r0, r4
11f8: e1a0100a mov r1, sl
11fc: ebffff1a bl e6c <_si5351_pll_reparent.isra.4>
if (ret) {
1200: e2507000 subs r7, r0, #0
1204: 1a0001b1 bne 18d0 <si5351_i2c_probe+0x8dc>
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
1208: e3a02001 mov r2, #1
120c: e5983004 ldr r3, [r8, #4]
1210: e1a0100a mov r1, sl
1214: e1a00004 mov r0, r4
1218: ebffff13 bl e6c <_si5351_pll_reparent.isra.4>
if (ret) {
121c: e2507000 subs r7, r0, #0
if (drvdata->variant != SI5351_VARIANT_C)
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
1220: 13a02001 movne r2, #1
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
if (ret) {
1224: 1a0001aa bne 18d4 <si5351_i2c_probe+0x8e0>
1228: e1a06008 mov r6, r8
122c: e3a09010 mov r9, #16
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1230: e3a05003 mov r5, #3
1234: e58d8014 str r8, [sp, #20]
return ret;
}
}
for (n = 0; n < 8; n++) {
ret = _si5351_msynth_reparent(drvdata, n,
1238: e5963008 ldr r3, [r6, #8]
* MSx_P1 = 0, MSx_P2 = 0, MSx_P3 = 1, MSx_INT = 1, MSx_DIVBY4 = 11b
*/
static int _si5351_msynth_reparent(struct si5351_driver_data *drvdata,
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
123c: e3530000 cmp r3, #0
1240: 0a000006 beq 1260 <si5351_i2c_probe+0x26c>
return 0;
if (num > 8)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1244: e3530001 cmp r3, #1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1248: e3a02020 mov r2, #32
124c: e1a01009 mov r1, r9
1250: e5940008 ldr r0, [r4, #8]
1254: 11a03002 movne r3, r2
1258: 03a03000 moveq r3, #0
125c: ebfffffe bl 0 <regmap_update_bits>
"failed to reparent multisynth %d to %d\n",
n, pdata->clkout[n].multisynth_src);
return ret;
}
ret = _si5351_clkout_reparent(drvdata, n,
1260: e596300c ldr r3, [r6, #12]
1264: e1a02007 mov r2, r7
1268: e1a0100a mov r1, sl
126c: e1a00004 mov r0, r4
1270: ebffff34 bl f48 <_si5351_clkout_reparent.isra.7>
pdata->clkout[n].clkout_src);
if (ret) {
1274: e3500000 cmp r0, #0
1278: 1a00019e bne 18f8 <si5351_i2c_probe+0x904>
u8 mask;
if (num > 8)
return -EINVAL;
switch (drive) {
127c: e5963010 ldr r3, [r6, #16]
1280: e2433002 sub r3, r3, #2
1284: e3530006 cmp r3, #6
1288: 979ff103 ldrls pc, [pc, r3, lsl #2]
128c: ea00000b b 12c0 <si5351_i2c_probe+0x2cc>
1290: 00001688 .word 0x00001688
1294: 000012c0 .word 0x000012c0
1298: 000012ac .word 0x000012ac
129c: 000012c0 .word 0x000012c0
12a0: 00001698 .word 0x00001698
12a4: 000012c0 .word 0x000012c0
12a8: 00001690 .word 0x00001690
12ac: e3a03001 mov r3, #1
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
12b0: e3a02003 mov r2, #3
12b4: e1a01009 mov r1, r9
12b8: e5940008 ldr r0, [r4, #8]
12bc: ebfffffe bl 0 <regmap_update_bits>
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
12c0: e3570003 cmp r7, #3
"failed set drive strength of clkout%d to %d\n",
n, pdata->clkout[n].drive);
return ret;
}
ret = _si5351_clkout_set_disable_state(drvdata, n,
12c4: e5962014 ldr r2, [r6, #20]
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
12c8: ca0000f4 bgt 16a0 <si5351_i2c_probe+0x6ac>
12cc: e1a03087 lsl r3, r7, #1
12d0: e3a01018 mov r1, #24
12d4: e6ef3073 uxtb r3, r3
u8 val;
if (num > 8)
return -EINVAL;
switch (state) {
12d8: e2420001 sub r0, r2, #1
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
SI5351_CLK7_4_DISABLE_STATE;
u8 shift = (num < 4) ? (2 * num) : (2 * (num-4));
u8 mask = SI5351_CLK_DISABLE_STATE_MASK << shift;
12dc: e1a02315 lsl r2, r5, r3
u8 val;
if (num > 8)
return -EINVAL;
switch (state) {
12e0: e3500003 cmp r0, #3
12e4: 979ff100 ldrls pc, [pc, r0, lsl #2]
12e8: ea000006 b 1308 <si5351_i2c_probe+0x314>
12ec: 000012fc .word 0x000012fc
12f0: 0000167c .word 0x0000167c
12f4: 00001670 .word 0x00001670
12f8: 00001668 .word 0x00001668
12fc: e3a03000 mov r3, #0
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1300: e5940008 ldr r0, [r4, #8]
1304: ebfffffe bl 0 <regmap_update_bits>
n, pdata->pll_src[n]);
return ret;
}
}
for (n = 0; n < 8; n++) {
1308: e2877001 add r7, r7, #1
130c: e2866018 add r6, r6, #24
1310: e3570008 cmp r7, #8
1314: e2899001 add r9, r9, #1
1318: 1affffc6 bne 1238 <si5351_i2c_probe+0x244>
n, pdata->clkout[n].disable_state);
return ret;
}
}
if (!IS_ERR(drvdata->pxtal))
131c: e5945014 ldr r5, [r4, #20]
1320: e3750a01 cmn r5, #4096 ; 0x1000
1324: 8a000003 bhi 1338 <si5351_i2c_probe+0x344>
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{
int ret;
ret = clk_prepare(clk);
1328: e1a00005 mov r0, r5
132c: ebfffffe bl 0 <clk_prepare>
if (ret)
1330: e3500000 cmp r0, #0
1334: 0a0000e5 beq 16d0 <si5351_i2c_probe+0x6dc>
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
1338: e5945028 ldr r5, [r4, #40] ; 0x28
133c: e3750a01 cmn r5, #4096 ; 0x1000
1340: 8a000003 bhi 1354 <si5351_i2c_probe+0x360>
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{
int ret;
ret = clk_prepare(clk);
1344: e1a00005 mov r0, r5
1348: ebfffffe bl 0 <clk_prepare>
if (ret)
134c: e3500000 cmp r0, #0
1350: 0a0000d7 beq 16b4 <si5351_i2c_probe+0x6c0>
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
1354: e28d6034 add r6, sp, #52 ; 0x34
init.name = si5351_input_names[0];
1358: e3003000 movw r3, #0
135c: e3403000 movt r3, #0
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
1360: e3a01014 mov r1, #20
1364: e1a00006 mov r0, r6
init.name = si5351_input_names[0];
1368: e1a05003 mov r5, r3
136c: e58d300c str r3, [sp, #12]
clk_prepare_enable(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
1370: ebfffffe bl 0 <__memzero>
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
1374: e59f3a94 ldr r3, [pc, #2708] ; 1e10 <si5351_i2c_probe+0xe1c>
init.flags = 0;
1378: e3a02000 mov r2, #0
if (!IS_ERR(drvdata->pclkin))
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
137c: e58d5034 str r5, [sp, #52] ; 0x34
init.ops = &si5351_xtal_ops;
init.flags = 0;
1380: e58d2044 str r2, [sp, #68] ; 0x44
clk_prepare_enable(drvdata->pclkin);
/* register xtal input clock gate */
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
1384: e58d3038 str r3, [sp, #56] ; 0x38
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
1388: e5940014 ldr r0, [r4, #20]
138c: e3700a01 cmn r0, #4096 ; 0x1000
1390: 8a000005 bhi 13ac <si5351_i2c_probe+0x3b8>
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
1394: ebfffffe bl 0 <__clk_get_name>
1398: e1a03004 mov r3, r4
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
139c: e3a02001 mov r2, #1
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
13a0: e5a30018 str r0, [r3, #24]!
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
13a4: e5cd2040 strb r2, [sp, #64] ; 0x40
init.name = si5351_input_names[0];
init.ops = &si5351_xtal_ops;
init.flags = 0;
if (!IS_ERR(drvdata->pxtal)) {
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
init.parent_names = &drvdata->pxtal_name;
13a8: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = 1;
}
drvdata->xtal.init = &init;
13ac: e5846024 str r6, [r4, #36] ; 0x24
clk = devm_clk_register(&client->dev, &drvdata->xtal);
13b0: e284101c add r1, r4, #28
13b4: e1a0000b mov r0, fp
13b8: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
13bc: e3700a01 cmn r0, #4096 ; 0x1000
drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
init.parent_names = &drvdata->pxtal_name;
init.num_parents = 1;
}
drvdata->xtal.init = &init;
clk = devm_clk_register(&client->dev, &drvdata->xtal);
13c0: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
13c4: 8a000091 bhi 1610 <si5351_i2c_probe+0x61c>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
13c8: e5943000 ldr r3, [r4]
13cc: e3530004 cmp r3, #4
13d0: 0a000217 beq 1c34 <si5351_i2c_probe+0xc40>
13d4: e3003000 movw r3, #0
13d8: e3403000 movt r3, #0
13dc: e58d3010 str r3, [sp, #16]
goto err_clk;
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
13e0: e3a05001 mov r5, #1
parent_names[0] = si5351_input_names[0];
13e4: e59d300c ldr r3, [sp, #12]
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
13e8: e3a09000 mov r9, #0
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
13ec: e3a01014 mov r1, #20
13f0: e1a00006 mov r0, r6
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
13f4: e59faa18 ldr sl, [pc, #2584] ; 1e14 <si5351_i2c_probe+0xe20>
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
13f8: e3007000 movw r7, #0
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
13fc: e58d3024 str r3, [sp, #36] ; 0x24
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
1400: e3407000 movt r7, #0
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
1404: e59d3010 ldr r3, [sp, #16]
1408: e58d3028 str r3, [sp, #40] ; 0x28
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
140c: e28d3024 add r3, sp, #36 ; 0x24
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
1410: e5844048 str r4, [r4, #72] ; 0x48
drvdata->pll[0].hw.init = &init;
1414: e5846044 str r6, [r4, #68] ; 0x44
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
parent_names[0] = si5351_input_names[0];
parent_names[1] = si5351_input_names[1];
/* register PLLA */
drvdata->pll[0].num = 0;
1418: e5c4905c strb r9, [r4, #92] ; 0x5c
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
141c: e58d3000 str r3, [sp]
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
1420: ebfffffe bl 0 <__memzero>
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1424: e284103c add r1, r4, #60 ; 0x3c
1428: e1a0000b mov r0, fp
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
142c: e59d3000 ldr r3, [sp]
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
1430: e58d9044 str r9, [sp, #68] ; 0x44
init.parent_names = parent_names;
init.num_parents = num_parents;
1434: e5cd5040 strb r5, [sp, #64] ; 0x40
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
1438: e58d303c str r3, [sp, #60] ; 0x3c
/* register PLLA */
drvdata->pll[0].num = 0;
drvdata->pll[0].drvdata = drvdata;
drvdata->pll[0].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_pll_names[0];
143c: e58d7034 str r7, [sp, #52] ; 0x34
init.ops = &si5351_pll_ops;
1440: e58da038 str sl, [sp, #56] ; 0x38
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1444: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1448: e3700a01 cmn r0, #4096 ; 0x1000
init.name = si5351_pll_names[0];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
144c: e1a03000 mov r3, r0
if (IS_ERR(clk)) {
1450: 8a000215 bhi 1cac <si5351_i2c_probe+0xcb8>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
1454: e3a03001 mov r3, #1
drvdata->pll[1].drvdata = drvdata;
1458: e584406c str r4, [r4, #108] ; 0x6c
ret = PTR_ERR(clk);
goto err_clk;
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
145c: e5c43080 strb r3, [r4, #128] ; 0x80
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
1460: e3a01014 mov r1, #20
}
/* register PLLB or VXCO (Si5351B) */
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
1464: e5846068 str r6, [r4, #104] ; 0x68
memset(&init, 0, sizeof(init));
1468: e1a00006 mov r0, r6
146c: ebfffffe bl 0 <__memzero>
if (drvdata->variant == SI5351_VARIANT_B) {
1470: e5943000 ldr r3, [r4]
1474: e3530003 cmp r3, #3
1478: 0a00009b beq 16ec <si5351_i2c_probe+0x6f8>
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
147c: e59d2000 ldr r2, [sp]
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
1480: e3003000 movw r3, #0
1484: e3403000 movt r3, #0
init.ops = &si5351_pll_ops;
1488: e58da038 str sl, [sp, #56] ; 0x38
init.flags = 0;
148c: e58d9044 str r9, [sp, #68] ; 0x44
init.parent_names = parent_names;
1490: e58d203c str r2, [sp, #60] ; 0x3c
init.num_parents = num_parents;
1494: e5cd5040 strb r5, [sp, #64] ; 0x40
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
} else {
init.name = si5351_pll_names[1];
1498: e58d3034 str r3, [sp, #52] ; 0x34
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
}
clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
149c: e2841060 add r1, r4, #96 ; 0x60
14a0: e1a0000b mov r0, fp
14a4: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
14a8: e3700a01 cmn r0, #4096 ; 0x1000
init.ops = &si5351_pll_ops;
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
}
clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
14ac: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
14b0: 8a000056 bhi 1610 <si5351_i2c_probe+0x61c>
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14b4: e5943000 ldr r3, [r4]
va_list ap);
extern __printf(3, 4)
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
static inline void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
return devm_kmalloc(dev, size, gfp | __GFP_ZERO);
14b8: e30820d0 movw r2, #32976 ; 0x80d0
parent_names[0] = si5351_pll_names[0];
14bc: e58d7024 str r7, [sp, #36] ; 0x24
14c0: e1a0000b mov r0, fp
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14c4: e3530002 cmp r3, #2
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
14c8: e5943000 ldr r3, [r4]
ret = PTR_ERR(clk);
goto err_clk;
}
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
14cc: 03a05003 moveq r5, #3
14d0: 03a0906c moveq r9, #108 ; 0x6c
14d4: 13a05008 movne r5, #8
14d8: 13a09e12 movne r9, #288 ; 0x120
14dc: 03a0a00c moveq sl, #12
14e0: 058d5008 streq r5, [sp, #8]
14e4: 13a0a020 movne sl, #32
14e8: 158d5008 strne r5, [sp, #8]
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
14ec: e3530003 cmp r3, #3
14f0: e1a01009 mov r1, r9
parent_names[1] = si5351_pll_names[2];
14f4: 03003000 movweq r3, #0
else
parent_names[1] = si5351_pll_names[1];
14f8: 13003000 movwne r3, #0
/* register clk multisync and clk out divider */
num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
parent_names[0] = si5351_pll_names[0];
if (drvdata->variant == SI5351_VARIANT_B)
parent_names[1] = si5351_pll_names[2];
14fc: 03403000 movteq r3, #0
else
parent_names[1] = si5351_pll_names[1];
1500: 13403000 movtne r3, #0
1504: e58d3028 str r3, [sp, #40] ; 0x28
1508: ebfffffe bl 0 <devm_kmalloc>
150c: e1a01009 mov r1, r9
1510: e30820d0 movw r2, #32976 ; 0x80d0
drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
1514: e5840084 str r0, [r4, #132] ; 0x84
1518: e1a0000b mov r0, fp
151c: ebfffffe bl 0 <devm_kmalloc>
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->clkout), GFP_KERNEL);
drvdata->onecell.clk_num = num_clocks;
1520: e5845010 str r5, [r4, #16]
1524: e1a0100a mov r1, sl
1528: e30820d0 movw r2, #32976 ; 0x80d0
else
parent_names[1] = si5351_pll_names[1];
drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
152c: e5840088 str r0, [r4, #136] ; 0x88
1530: e1a0000b mov r0, fp
1534: ebfffffe bl 0 <devm_kmalloc>
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1538: e5943084 ldr r3, [r4, #132] ; 0x84
153c: e3530000 cmp r3, #0
sizeof(*drvdata->msynth), GFP_KERNEL);
drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
sizeof(*drvdata->clkout), GFP_KERNEL);
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
1540: e584000c str r0, [r4, #12]
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1544: 0a000072 beq 1714 <si5351_i2c_probe+0x720>
1548: e5942088 ldr r2, [r4, #136] ; 0x88
154c: e3500000 cmp r0, #0
1550: 13520000 cmpne r2, #0
1554: 03a09001 moveq r9, #1
1558: 13a09000 movne r9, #0
155c: 0a00006c beq 1714 <si5351_i2c_probe+0x720>
!drvdata->onecell.clks)) {
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
1560: e3005000 movw r5, #0
1564: e59fa8ac ldr sl, [pc, #2220] ; 1e18 <si5351_i2c_probe+0xe24>
1568: e3405000 movt r5, #0
156c: ea000004 b 1584 <si5351_i2c_probe+0x590>
1570: e59d3008 ldr r3, [sp, #8]
1574: e1590003 cmp r9, r3
1578: 0a00006b beq 172c <si5351_i2c_probe+0x738>
157c: e5943084 ldr r3, [r4, #132] ; 0x84
1580: e5ba5004 ldr r5, [sl, #4]!
1584: e1a07289 lsl r7, r9, #5
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
1588: e3a01014 mov r1, #20
158c: e0877109 add r7, r7, r9, lsl #2
1590: e1a00006 mov r0, r6
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
drvdata->msynth[n].num = n;
1594: e0833007 add r3, r3, r7
1598: e2888018 add r8, r8, #24
159c: e5c39020 strb r9, [r3, #32]
!drvdata->onecell.clks)) {
ret = -ENOMEM;
goto err_clk;
}
for (n = 0; n < num_clocks; n++) {
15a0: e2899001 add r9, r9, #1
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
15a4: e5943084 ldr r3, [r4, #132] ; 0x84
15a8: e0833007 add r3, r3, r7
15ac: e583400c str r4, [r3, #12]
drvdata->msynth[n].hw.init = &init;
15b0: e5943084 ldr r3, [r4, #132] ; 0x84
15b4: e0833007 add r3, r3, r7
15b8: e5836008 str r6, [r3, #8]
memset(&init, 0, sizeof(init));
15bc: ebfffffe bl 0 <__memzero>
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
15c0: e59f2854 ldr r2, [pc, #2132] ; 1e1c <si5351_i2c_probe+0xe28>
init.flags = 0;
if (pdata->clkout[n].pll_master)
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = 2;
15c4: e3a03002 mov r3, #2
clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
15c8: e1a0000b mov r0, fp
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
15cc: e58d2038 str r2, [sp, #56] ; 0x38
init.flags = 0;
15d0: e3a02000 mov r2, #0
for (n = 0; n < num_clocks; n++) {
drvdata->msynth[n].num = n;
drvdata->msynth[n].drvdata = drvdata;
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
15d4: e58d5034 str r5, [sp, #52] ; 0x34
init.ops = &si5351_msynth_ops;
init.flags = 0;
15d8: e58d2044 str r2, [sp, #68] ; 0x44
if (pdata->clkout[n].pll_master)
15dc: e5d81000 ldrb r1, [r8]
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = 2;
15e0: e5cd3040 strb r3, [sp, #64] ; 0x40
drvdata->msynth[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_msynth_names[n];
init.ops = &si5351_msynth_ops;
init.flags = 0;
if (pdata->clkout[n].pll_master)
15e4: e1510002 cmp r1, r2
init.flags |= CLK_SET_RATE_PARENT;
15e8: 13a02004 movne r2, #4
15ec: 158d2044 strne r2, [sp, #68] ; 0x44
init.parent_names = parent_names;
15f0: e59d2000 ldr r2, [sp]
15f4: e58d203c str r2, [sp, #60] ; 0x3c
init.num_parents = 2;
clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
15f8: e5941084 ldr r1, [r4, #132] ; 0x84
15fc: e0811007 add r1, r1, r7
1600: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1604: e3700a01 cmn r0, #4096 ; 0x1000
1608: 9affffd8 bls 1570 <si5351_i2c_probe+0x57c>
160c: e1a05000 mov r5, r0
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
if (IS_ERR(clk)) {
dev_err(&client->dev, "unable to register %s\n",
1610: e3001000 movw r1, #0
1614: e1a0000b mov r0, fp
1618: e3401000 movt r1, #0
161c: e59d2034 ldr r2, [sp, #52] ; 0x34
1620: ebfffffe bl 0 <dev_err>
}
return 0;
err_clk:
if (!IS_ERR(drvdata->pxtal))
1624: e5946014 ldr r6, [r4, #20]
1628: e3760a01 cmn r6, #4096 ; 0x1000
162c: 8a000003 bhi 1640 <si5351_i2c_probe+0x64c>
}
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
static inline void clk_disable_unprepare(struct clk *clk)
{
clk_disable(clk);
1630: e1a00006 mov r0, r6
1634: ebfffffe bl 0 <clk_disable>
clk_unprepare(clk);
1638: e1a00006 mov r0, r6
163c: ebfffffe bl 0 <clk_unprepare>
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
1640: e5944028 ldr r4, [r4, #40] ; 0x28
1644: e3740a01 cmn r4, #4096 ; 0x1000
1648: 8a0000a8 bhi 18f0 <si5351_i2c_probe+0x8fc>
}
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
static inline void clk_disable_unprepare(struct clk *clk)
{
clk_disable(clk);
164c: e1a00004 mov r0, r4
1650: ebfffffe bl 0 <clk_disable>
clk_unprepare(clk);
1654: e1a00004 mov r0, r4
1658: ebfffffe bl 0 <clk_unprepare>
clk_disable_unprepare(drvdata->pclkin);
return ret;
165c: e1a00005 mov r0, r5
}
1660: e28dd04c add sp, sp, #76 ; 0x4c
1664: e8bd8ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp, pc}
1668: e1a03002 mov r3, r2
166c: eaffff23 b 1300 <si5351_i2c_probe+0x30c>
1670: e3a00002 mov r0, #2
1674: e1a03310 lsl r3, r0, r3
1678: eaffff20 b 1300 <si5351_i2c_probe+0x30c>
167c: e3a00001 mov r0, #1
1680: e1a03310 lsl r3, r0, r3
1684: eaffff1d b 1300 <si5351_i2c_probe+0x30c>
u8 mask;
if (num > 8)
return -EINVAL;
switch (drive) {
1688: e3a03000 mov r3, #0
168c: eaffff07 b 12b0 <si5351_i2c_probe+0x2bc>
1690: e3a03003 mov r3, #3
1694: eaffff05 b 12b0 <si5351_i2c_probe+0x2bc>
1698: e3a03002 mov r3, #2
169c: eaffff03 b 12b0 <si5351_i2c_probe+0x2bc>
16a0: e287307c add r3, r7, #124 ; 0x7c
static int _si5351_clkout_set_disable_state(
struct si5351_driver_data *drvdata, int num,
enum si5351_disable_state state)
{
u8 reg = (num < 4) ? SI5351_CLK3_0_DISABLE_STATE :
16a4: e3a01019 mov r1, #25
16a8: e1a03083 lsl r3, r3, #1
16ac: e6ef3073 uxtb r3, r3
16b0: eaffff08 b 12d8 <si5351_i2c_probe+0x2e4>
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
16b4: e1a00005 mov r0, r5
16b8: ebfffffe bl 0 <clk_enable>
if (ret)
16bc: e3500000 cmp r0, #0
16c0: 0affff23 beq 1354 <si5351_i2c_probe+0x360>
clk_unprepare(clk);
16c4: e1a00005 mov r0, r5
16c8: ebfffffe bl 0 <clk_unprepare>
16cc: eaffff20 b 1354 <si5351_i2c_probe+0x360>
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
16d0: e1a00005 mov r0, r5
16d4: ebfffffe bl 0 <clk_enable>
if (ret)
16d8: e3500000 cmp r0, #0
16dc: 0affff15 beq 1338 <si5351_i2c_probe+0x344>
clk_unprepare(clk);
16e0: e1a00005 mov r0, r5
16e4: ebfffffe bl 0 <clk_unprepare>
16e8: eaffff12 b 1338 <si5351_i2c_probe+0x344>
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
16ec: e3003000 movw r3, #0
init.ops = &si5351_vxco_ops;
16f0: e28aa050 add sl, sl, #80 ; 0x50
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
16f4: e3403000 movt r3, #0
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
16f8: e3a02010 mov r2, #16
init.parent_names = NULL;
16fc: e58d903c str r9, [sp, #60] ; 0x3c
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
init.ops = &si5351_vxco_ops;
1700: e58da038 str sl, [sp, #56] ; 0x38
init.flags = CLK_IS_ROOT;
init.parent_names = NULL;
init.num_parents = 0;
1704: e5cd9040 strb r9, [sp, #64] ; 0x40
drvdata->pll[1].num = 1;
drvdata->pll[1].drvdata = drvdata;
drvdata->pll[1].hw.init = &init;
memset(&init, 0, sizeof(init));
if (drvdata->variant == SI5351_VARIANT_B) {
init.name = si5351_pll_names[2];
1708: e58d3034 str r3, [sp, #52] ; 0x34
init.ops = &si5351_vxco_ops;
init.flags = CLK_IS_ROOT;
170c: e58d2044 str r2, [sp, #68] ; 0x44
1710: eaffff61 b 149c <si5351_i2c_probe+0x4a8>
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1714: e3000000 movw r0, #0
1718: e30015e8 movw r1, #1512 ; 0x5e8
171c: e3400000 movt r0, #0
!drvdata->onecell.clks)) {
ret = -ENOMEM;
1720: e3e0500b mvn r5, #11
drvdata->onecell.clk_num = num_clocks;
drvdata->onecell.clks = devm_kzalloc(&client->dev,
num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1724: ebfffffe bl 0 <warn_slowpath_null>
1728: eaffffbd b 1624 <si5351_i2c_probe+0x630>
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
172c: e5942000 ldr r2, [r4]
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
1730: e3003000 movw r3, #0
1734: e59f96dc ldr r9, [pc, #1756] ; 1e18 <si5351_i2c_probe+0xe24>
1738: e3005000 movw r5, #0
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
173c: e3520004 cmp r2, #4
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
1740: e3002000 movw r2, #0
1744: e3402000 movt r2, #0
1748: e58d201c str r2, [sp, #28]
ret = PTR_ERR(clk);
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
174c: 13a01003 movne r1, #3
1750: 03a01004 moveq r1, #4
1754: e58d1018 str r1, [sp, #24]
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
1758: e3405000 movt r5, #0
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
175c: e59d100c ldr r1, [sp, #12]
parent_names[3] = si5351_input_names[1];
1760: e3403000 movt r3, #0
1764: e5942088 ldr r2, [r4, #136] ; 0x88
1768: e289a070 add sl, r9, #112 ; 0x70
176c: e58db00c str fp, [sp, #12]
for (n = 0; n < num_clocks; n++) {
1770: e3a07000 mov r7, #0
goto err_clk;
}
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
1774: e58d102c str r1, [sp, #44] ; 0x2c
parent_names[3] = si5351_input_names[1];
1778: e1a0b004 mov fp, r4
177c: e59d1010 ldr r1, [sp, #16]
1780: e1a04005 mov r4, r5
1784: e1a05009 mov r5, r9
1788: e1a09006 mov r9, r6
178c: e59d6014 ldr r6, [sp, #20]
1790: e58d1030 str r1, [sp, #48] ; 0x30
1794: e1a01003 mov r1, r3
1798: ea000005 b 17b4 <si5351_i2c_probe+0x7c0>
for (n = 0; n < num_clocks; n++) {
179c: e59d3008 ldr r3, [sp, #8]
17a0: e1570003 cmp r7, r3
17a4: aa000147 bge 1cc8 <si5351_i2c_probe+0xcd4>
17a8: e5b51004 ldr r1, [r5, #4]!
17ac: e59b2088 ldr r2, [fp, #136] ; 0x88
17b0: e5ba4004 ldr r4, [sl, #4]!
17b4: e1a08287 lsl r8, r7, #5
parent_names[0] = si5351_msynth_names[n];
17b8: e58d1024 str r1, [sp, #36] ; 0x24
17bc: e0888107 add r8, r8, r7, lsl #2
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17c0: e59d101c ldr r1, [sp, #28]
17c4: e3570003 cmp r7, #3
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
17c8: e0822008 add r2, r2, r8
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17cc: e3003000 movw r3, #0
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
17d0: e1a00009 mov r0, r9
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
17d4: e3403000 movt r3, #0
17d8: d1a01003 movle r1, r3
17dc: e58d1028 str r1, [sp, #40] ; 0x28
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
17e0: e5c27020 strb r7, [r2, #32]
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
17e4: e3a01014 mov r1, #20
parent_names[0] = si5351_msynth_names[n];
parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
si5351_msynth_names[4];
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
17e8: e59b2088 ldr r2, [fp, #136] ; 0x88
17ec: e0822008 add r2, r2, r8
17f0: e582b00c str fp, [r2, #12]
drvdata->clkout[n].hw.init = &init;
17f4: e59b2088 ldr r2, [fp, #136] ; 0x88
17f8: e0822008 add r2, r2, r8
17fc: e5829008 str r9, [r2, #8]
memset(&init, 0, sizeof(init));
1800: ebfffffe bl 0 <__memzero>
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
1804: e59f3614 ldr r3, [pc, #1556] ; 1e20 <si5351_i2c_probe+0xe2c>
init.flags = 0;
1808: e3a02000 mov r2, #0
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
180c: e58d3038 str r3, [sp, #56] ; 0x38
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
1810: e59d3000 ldr r3, [sp]
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
1814: e58d2044 str r2, [sp, #68] ; 0x44
drvdata->clkout[n].num = n;
drvdata->clkout[n].drvdata = drvdata;
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
1818: e58d4034 str r4, [sp, #52] ; 0x34
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
181c: e596200c ldr r2, [r6, #12]
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
1820: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = num_parents;
1824: e5dd3018 ldrb r3, [sp, #24]
drvdata->clkout[n].hw.init = &init;
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
1828: e3520001 cmp r2, #1
init.flags |= CLK_SET_RATE_PARENT;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
182c: e59d000c ldr r0, [sp, #12]
memset(&init, 0, sizeof(init));
init.name = si5351_clkout_names[n];
init.ops = &si5351_clkout_ops;
init.flags = 0;
if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
init.flags |= CLK_SET_RATE_PARENT;
1830: 03a02004 moveq r2, #4
1834: 058d2044 streq r2, [sp, #68] ; 0x44
init.parent_names = parent_names;
init.num_parents = num_parents;
1838: e5cd3040 strb r3, [sp, #64] ; 0x40
clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
183c: e59b1088 ldr r1, [fp, #136] ; 0x88
1840: e0811008 add r1, r1, r8
1844: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1848: e3700a01 cmn r0, #4096 ; 0x1000
184c: 8a000035 bhi 1928 <si5351_i2c_probe+0x934>
dev_err(&client->dev, "unable to register %s\n",
init.name);
ret = PTR_ERR(clk);
goto err_clk;
}
drvdata->onecell.clks[n] = clk;
1850: e59b100c ldr r1, [fp, #12]
1854: e2866018 add r6, r6, #24
1858: e7810107 str r0, [r1, r7, lsl #2]
}
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
parent_names[2] = si5351_input_names[0];
parent_names[3] = si5351_input_names[1];
for (n = 0; n < num_clocks; n++) {
185c: e2877001 add r7, r7, #1
goto err_clk;
}
drvdata->onecell.clks[n] = clk;
/* set initial clkout rate */
if (pdata->clkout[n].rate != 0) {
1860: e5961004 ldr r1, [r6, #4]
1864: e3510000 cmp r1, #0
1868: 0affffcb beq 179c <si5351_i2c_probe+0x7a8>
int ret;
ret = clk_set_rate(clk, pdata->clkout[n].rate);
186c: ebfffffe bl 0 <clk_set_rate>
if (ret != 0) {
1870: e2502000 subs r2, r0, #0
1874: 0affffc8 beq 179c <si5351_i2c_probe+0x7a8>
dev_err(&client->dev, "Cannot set rate : %d\n",
1878: e3001000 movw r1, #0
187c: e59d000c ldr r0, [sp, #12]
1880: e3401000 movt r1, #0
1884: ebfffffe bl 0 <dev_err>
1888: eaffffc3 b 179c <si5351_i2c_probe+0x7a8>
/*
* Check for valid parent clock: VARIANT_A and VARIANT_B need XTAL,
* VARIANT_C can have CLKIN instead.
*/
if (IS_ERR(drvdata->pxtal) &&
188c: e5943000 ldr r3, [r4]
1890: e3530004 cmp r3, #4
1894: 1a000001 bne 18a0 <si5351_i2c_probe+0x8ac>
(drvdata->variant != SI5351_VARIANT_C || IS_ERR(drvdata->pclkin))) {
1898: e3700a01 cmn r0, #4096 ; 0x1000
189c: 9afffe40 bls 11a4 <si5351_i2c_probe+0x1b0>
dev_err(&client->dev, "missing parent clock\n");
18a0: e3001000 movw r1, #0
18a4: e1a0000b mov r0, fp
18a8: e3401000 movt r1, #0
18ac: ebfffffe bl 0 <dev_err>
return -EINVAL;
18b0: e3e00015 mvn r0, #21
18b4: eafffe14 b 110c <si5351_i2c_probe+0x118>
}
drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
if (IS_ERR(drvdata->regmap)) {
dev_err(&client->dev, "failed to allocate register map\n");
18b8: e3001000 movw r1, #0
18bc: e1a0000b mov r0, fp
18c0: e3401000 movt r1, #0
18c4: ebfffffe bl 0 <dev_err>
return (void *) error;
}
static inline long __must_check PTR_ERR(__force const void *ptr)
{
return (long) ptr;
18c8: e5940008 ldr r0, [r4, #8]
return PTR_ERR(drvdata->regmap);
18cc: eafffe0e b 110c <si5351_i2c_probe+0x118>
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
if (ret) {
18d0: e3a02000 mov r2, #0
dev_err(&client->dev,
18d4: e3001000 movw r1, #0
18d8: e1a0000b mov r0, fp
18dc: e7983102 ldr r3, [r8, r2, lsl #2]
18e0: e3401000 movt r1, #0
18e4: ebfffffe bl 0 <dev_err>
si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
/* setup clock configuration */
for (n = 0; n < 2; n++) {
ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
18e8: e1a00007 mov r0, r7
if (ret) {
dev_err(&client->dev,
"failed to reparent pll %d to %d\n",
n, pdata->pll_src[n]);
return ret;
18ec: eafffe06 b 110c <si5351_i2c_probe+0x118>
err_clk:
if (!IS_ERR(drvdata->pxtal))
clk_disable_unprepare(drvdata->pxtal);
if (!IS_ERR(drvdata->pclkin))
clk_disable_unprepare(drvdata->pclkin);
return ret;
18f0: e1a00005 mov r0, r5
18f4: eafffe04 b 110c <si5351_i2c_probe+0x118>
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
18f8: e1a03287 lsl r3, r7, #5
}
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
18fc: e3001000 movw r1, #0
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
1900: e0433187 sub r3, r3, r7, lsl #3
1904: e1a04000 mov r4, r0
1908: e0888003 add r8, r8, r3
}
ret = _si5351_clkout_reparent(drvdata, n,
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
190c: e1a0000b mov r0, fp
1910: e1a02007 mov r2, r7
1914: e3401000 movt r1, #0
1918: e598300c ldr r3, [r8, #12]
191c: ebfffffe bl 0 <dev_err>
"failed to reparent multisynth %d to %d\n",
n, pdata->clkout[n].multisynth_src);
return ret;
}
ret = _si5351_clkout_reparent(drvdata, n,
1920: e1a00004 mov r0, r4
pdata->clkout[n].clkout_src);
if (ret) {
dev_err(&client->dev,
"failed to reparent clkout %d to %d\n",
n, pdata->clkout[n].clkout_src);
return ret;
1924: eafffdf8 b 110c <si5351_i2c_probe+0x118>
1928: e1a0400b mov r4, fp
192c: e1a05000 mov r5, r0
1930: e59db00c ldr fp, [sp, #12]
1934: eaffff35 b 1610 <si5351_i2c_probe+0x61c>
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1938: e3a01000 mov r1, #0
193c: e1a00005 mov r0, r5
1940: ebfffffe bl 0 <of_get_next_child>
1944: e2504000 subs r4, r0, #0
1948: 159d9000 ldrne r9, [sp]
194c: 0a000099 beq 1bb8 <si5351_i2c_probe+0xbc4>
static inline int of_property_read_u32(const struct device_node *np,
const char *propname,
u32 *out_value)
{
return of_property_read_u32_array(np, propname, out_value, 1);
1950: e3001000 movw r1, #0
1954: e3a03001 mov r3, #1
1958: e3401000 movt r1, #0
195c: e1a02009 mov r2, r9
1960: e1a00004 mov r0, r4
1964: ebfffffe bl 0 <of_property_read_u32_array>
if (of_property_read_u32(child, "reg", &num)) {
1968: e3500000 cmp r0, #0
196c: 1a000110 bne 1db4 <si5351_i2c_probe+0xdc0>
dev_err(&client->dev, "missing reg property of %s\n",
child->name);
return -EINVAL;
}
if (num >= 8 ||
1970: e59d2024 ldr r2, [sp, #36] ; 0x24
1974: e3520007 cmp r2, #7
1978: ca000107 bgt 1d9c <si5351_i2c_probe+0xda8>
(variant == SI5351_VARIANT_A3 && num >= 3)) {
197c: e3520002 cmp r2, #2
1980: d3a03000 movle r3, #0
1984: c3a03001 movgt r3, #1
1988: e3570002 cmp r7, #2
198c: 13a03000 movne r3, #0
1990: e3530000 cmp r3, #0
1994: 1a000100 bne 1d9c <si5351_i2c_probe+0xda8>
1998: e28d6034 add r6, sp, #52 ; 0x34
199c: e3001000 movw r1, #0
19a0: e3401000 movt r1, #0
19a4: e3a03001 mov r3, #1
19a8: e1a02006 mov r2, r6
19ac: e1a00004 mov r0, r4
19b0: ebfffffe bl 0 <of_property_read_u32_array>
dev_err(&client->dev, "invalid clkout %d\n", num);
return -EINVAL;
}
if (!of_property_read_u32(child, "silabs,multisynth-source",
19b4: e3500000 cmp r0, #0
19b8: 1a00000a bne 19e8 <si5351_i2c_probe+0x9f4>
&val)) {
switch (val) {
19bc: e59d2034 ldr r2, [sp, #52] ; 0x34
19c0: e3520000 cmp r2, #0
19c4: 0a0000d5 beq 1d20 <si5351_i2c_probe+0xd2c>
19c8: e3520001 cmp r2, #1
19cc: 1a0000cc bne 1d04 <si5351_i2c_probe+0xd10>
case 0:
pdata->clkout[num].multisynth_src =
SI5351_MULTISYNTH_SRC_VCO0;
break;
case 1:
pdata->clkout[num].multisynth_src =
19d0: e59d2024 ldr r2, [sp, #36] ; 0x24
19d4: e3a01002 mov r1, #2
19d8: e1a03282 lsl r3, r2, #5
19dc: e0433182 sub r3, r3, r2, lsl #3
19e0: e0883003 add r3, r8, r3
19e4: e5831008 str r1, [r3, #8]
19e8: e3001000 movw r1, #0
19ec: e3a03001 mov r3, #1
19f0: e3401000 movt r1, #0
19f4: e1a02006 mov r2, r6
19f8: e1a00004 mov r0, r4
19fc: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
1a00: e3500000 cmp r0, #0
1a04: 1a00000e bne 1a44 <si5351_i2c_probe+0xa50>
switch (val) {
1a08: e59d2034 ldr r2, [sp, #52] ; 0x34
1a0c: e3520003 cmp r2, #3
1a10: 979ff102 ldrls pc, [pc, r2, lsl #2]
1a14: ea0000cc b 1d4c <si5351_i2c_probe+0xd58>
1a18: 00001b0c .word 0x00001b0c
1a1c: 00001af0 .word 0x00001af0
1a20: 00001ad4 .word 0x00001ad4
1a24: 00001a28 .word 0x00001a28
case 2:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_XTAL;
break;
case 3:
if (variant != SI5351_VARIANT_C) {
1a28: e3570004 cmp r7, #4
1a2c: 1a0000ee bne 1dec <si5351_i2c_probe+0xdf8>
dev_err(&client->dev,
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
}
pdata->clkout[num].clkout_src =
1a30: e59d2024 ldr r2, [sp, #36] ; 0x24
1a34: e1a03282 lsl r3, r2, #5
1a38: e0433182 sub r3, r3, r2, lsl #3
1a3c: e0883003 add r3, r8, r3
1a40: e583700c str r7, [r3, #12]
1a44: e3001000 movw r1, #0
1a48: e3a03001 mov r3, #1
1a4c: e3401000 movt r1, #0
1a50: e1a02006 mov r2, r6
1a54: e1a00004 mov r0, r4
1a58: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,drive-strength",
1a5c: e3500000 cmp r0, #0
1a60: 1a00000b bne 1a94 <si5351_i2c_probe+0xaa0>
&val)) {
switch (val) {
1a64: e59d2034 ldr r2, [sp, #52] ; 0x34
1a68: e3520008 cmp r2, #8
1a6c: 8a0000d7 bhi 1dd0 <si5351_i2c_probe+0xddc>
1a70: e3a03001 mov r3, #1
1a74: e1a03213 lsl r3, r3, r2
1a78: e3130f55 tst r3, #340 ; 0x154
1a7c: 0a0000d3 beq 1dd0 <si5351_i2c_probe+0xddc>
case SI5351_DRIVE_2MA:
case SI5351_DRIVE_4MA:
case SI5351_DRIVE_6MA:
case SI5351_DRIVE_8MA:
pdata->clkout[num].drive = val;
1a80: e59d1024 ldr r1, [sp, #36] ; 0x24
1a84: e1a03281 lsl r3, r1, #5
1a88: e0433181 sub r3, r3, r1, lsl #3
1a8c: e0883003 add r3, r8, r3
1a90: e5832010 str r2, [r3, #16]
1a94: e3001000 movw r1, #0
1a98: e3a03001 mov r3, #1
1a9c: e3401000 movt r1, #0
1aa0: e1a02006 mov r2, r6
1aa4: e1a00004 mov r0, r4
1aa8: ebfffffe bl 0 <of_property_read_u32_array>
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "silabs,disable-state",
1aac: e3500000 cmp r0, #0
1ab0: 1a000022 bne 1b40 <si5351_i2c_probe+0xb4c>
&val)) {
switch (val) {
1ab4: e59d2034 ldr r2, [sp, #52] ; 0x34
1ab8: e3520003 cmp r2, #3
1abc: 979ff102 ldrls pc, [pc, r2, lsl #2]
1ac0: ea0000a8 b 1d68 <si5351_i2c_probe+0xd74>
1ac4: 00001bfc .word 0x00001bfc
1ac8: 00001be0 .word 0x00001be0
1acc: 00001bc4 .word 0x00001bc4
1ad0: 00001b28 .word 0x00001b28
case 1:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_MSYNTH_0_4;
break;
case 2:
pdata->clkout[num].clkout_src =
1ad4: e59d2024 ldr r2, [sp, #36] ; 0x24
1ad8: e3a01003 mov r1, #3
1adc: e1a03282 lsl r3, r2, #5
1ae0: e0433182 sub r3, r3, r2, lsl #3
1ae4: e0883003 add r3, r8, r3
1ae8: e583100c str r1, [r3, #12]
1aec: eaffffd4 b 1a44 <si5351_i2c_probe+0xa50>
case 0:
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_MSYNTH_N;
break;
case 1:
pdata->clkout[num].clkout_src =
1af0: e59d2024 ldr r2, [sp, #36] ; 0x24
1af4: e3a01002 mov r1, #2
1af8: e1a03282 lsl r3, r2, #5
1afc: e0433182 sub r3, r3, r2, lsl #3
1b00: e0883003 add r3, r8, r3
1b04: e583100c str r1, [r3, #12]
1b08: eaffffcd b 1a44 <si5351_i2c_probe+0xa50>
}
if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
switch (val) {
case 0:
pdata->clkout[num].clkout_src =
1b0c: e59d2024 ldr r2, [sp, #36] ; 0x24
1b10: e3a01001 mov r1, #1
1b14: e1a03282 lsl r3, r2, #5
1b18: e0433182 sub r3, r3, r2, lsl #3
1b1c: e0883003 add r3, r8, r3
1b20: e583100c str r1, [r3, #12]
1b24: eaffffc6 b 1a44 <si5351_i2c_probe+0xa50>
case 2:
pdata->clkout[num].disable_state =
SI5351_DISABLE_FLOATING;
break;
case 3:
pdata->clkout[num].disable_state =
1b28: e59d2024 ldr r2, [sp, #36] ; 0x24
1b2c: e3a01004 mov r1, #4
1b30: e1a03282 lsl r3, r2, #5
1b34: e0433182 sub r3, r3, r2, lsl #3
1b38: e0883003 add r3, r8, r3
1b3c: e5831014 str r1, [r3, #20]
1b40: e3001000 movw r1, #0
1b44: e3a03001 mov r3, #1
1b48: e1a02006 mov r2, r6
1b4c: e3401000 movt r1, #0
1b50: e1a00004 mov r0, r4
1b54: ebfffffe bl 0 <of_property_read_u32_array>
* Returns true if the property exist false otherwise.
*/
static inline bool of_property_read_bool(const struct device_node *np,
const char *propname)
{
struct property *prop = of_find_property(np, propname, NULL);
1b58: e3001000 movw r1, #0
1b5c: e3401000 movt r1, #0
return -EINVAL;
}
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
1b60: e59d6024 ldr r6, [sp, #36] ; 0x24
val, num);
return -EINVAL;
}
}
if (!of_property_read_u32(child, "clock-frequency", &val))
1b64: e3500000 cmp r0, #0
1b68: e1a00004 mov r0, r4
pdata->clkout[num].rate = val;
1b6c: 02866001 addeq r6, r6, #1
1b70: 059d2034 ldreq r2, [sp, #52] ; 0x34
1b74: 12866001 addne r6, r6, #1
1b78: 01a03286 lsleq r3, r6, #5
1b7c: 00433186 subeq r3, r3, r6, lsl #3
1b80: 00883003 addeq r3, r8, r3
1b84: 05832004 streq r2, [r3, #4]
1b88: e3a02000 mov r2, #0
1b8c: ebfffffe bl 0 <of_find_property>
pdata->clkout[num].pll_master =
1b90: e1a03286 lsl r3, r6, #5
1b94: e0436186 sub r6, r3, r6, lsl #3
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1b98: e1a01004 mov r1, r4
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
1b9c: e2903000 adds r3, r0, #0
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1ba0: e1a00005 mov r0, r5
}
if (!of_property_read_u32(child, "clock-frequency", &val))
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
1ba4: 13a03001 movne r3, #1
1ba8: e7c83006 strb r3, [r8, r6]
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
1bac: ebfffffe bl 0 <of_get_next_child>
1bb0: e2504000 subs r4, r0, #0
1bb4: 1affff65 bne 1950 <si5351_i2c_probe+0x95c>
pdata->clkout[num].rate = val;
pdata->clkout[num].pll_master =
of_property_read_bool(child, "silabs,pll-master");
}
client->dev.platform_data = pdata;
1bb8: e59d3004 ldr r3, [sp, #4]
1bbc: e58380a0 str r8, [r3, #160] ; 0xa0
1bc0: eafffd5b b 1134 <si5351_i2c_probe+0x140>
case 1:
pdata->clkout[num].disable_state =
SI5351_DISABLE_HIGH;
break;
case 2:
pdata->clkout[num].disable_state =
1bc4: e59d2024 ldr r2, [sp, #36] ; 0x24
1bc8: e3a01003 mov r1, #3
1bcc: e1a03282 lsl r3, r2, #5
1bd0: e0433182 sub r3, r3, r2, lsl #3
1bd4: e0883003 add r3, r8, r3
1bd8: e5831014 str r1, [r3, #20]
1bdc: eaffffd7 b 1b40 <si5351_i2c_probe+0xb4c>
case 0:
pdata->clkout[num].disable_state =
SI5351_DISABLE_LOW;
break;
case 1:
pdata->clkout[num].disable_state =
1be0: e59d2024 ldr r2, [sp, #36] ; 0x24
1be4: e3a01002 mov r1, #2
1be8: e1a03282 lsl r3, r2, #5
1bec: e0433182 sub r3, r3, r2, lsl #3
1bf0: e0883003 add r3, r8, r3
1bf4: e5831014 str r1, [r3, #20]
1bf8: eaffffd0 b 1b40 <si5351_i2c_probe+0xb4c>
if (!of_property_read_u32(child, "silabs,disable-state",
&val)) {
switch (val) {
case 0:
pdata->clkout[num].disable_state =
1bfc: e59d2024 ldr r2, [sp, #36] ; 0x24
1c00: e3a01001 mov r1, #1
1c04: e1a03282 lsl r3, r2, #5
1c08: e0433182 sub r3, r3, r2, lsl #3
1c0c: e0883003 add r3, r8, r3
1c10: e5831014 str r1, [r3, #20]
1c14: eaffffc9 b 1b40 <si5351_i2c_probe+0xb4c>
return -EINVAL;
}
p = of_prop_next_u32(prop, p, &val);
if (!p) {
dev_err(&client->dev,
1c18: e3001000 movw r1, #0
1c1c: e1a0000b mov r0, fp
1c20: e3401000 movt r1, #0
1c24: e59d2024 ldr r2, [sp, #36] ; 0x24
1c28: ebfffffe bl 0 <dev_err>
"missing pll-source for pll %d\n", num);
return -EINVAL;
1c2c: e3e00015 mvn r0, #21
1c30: eafffd35 b 110c <si5351_i2c_probe+0x118>
goto err_clk;
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
1c34: e1a00006 mov r0, r6
1c38: e3a01014 mov r1, #20
1c3c: ebfffffe bl 0 <__memzero>
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
1c40: e59f31dc ldr r3, [pc, #476] ; 1e24 <si5351_i2c_probe+0xe30>
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c44: e3002000 movw r2, #0
1c48: e3402000 movt r2, #0
init.ops = &si5351_clkin_ops;
1c4c: e58d3038 str r3, [sp, #56] ; 0x38
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c50: e58d2034 str r2, [sp, #52] ; 0x34
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
1c54: e5940028 ldr r0, [r4, #40] ; 0x28
}
/* register clkin input clock gate */
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
1c58: e58d2010 str r2, [sp, #16]
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
1c5c: e3700a01 cmn r0, #4096 ; 0x1000
1c60: 8a000005 bhi 1c7c <si5351_i2c_probe+0xc88>
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
1c64: ebfffffe bl 0 <__clk_get_name>
1c68: e1a03004 mov r3, r4
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
1c6c: e3a02001 mov r2, #1
if (drvdata->variant == SI5351_VARIANT_C) {
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
1c70: e5a3002c str r0, [r3, #44]! ; 0x2c
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
1c74: e5cd2040 strb r2, [sp, #64] ; 0x40
memset(&init, 0, sizeof(init));
init.name = si5351_input_names[1];
init.ops = &si5351_clkin_ops;
if (!IS_ERR(drvdata->pclkin)) {
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
init.parent_names = &drvdata->pclkin_name;
1c78: e58d303c str r3, [sp, #60] ; 0x3c
init.num_parents = 1;
}
drvdata->clkin.init = &init;
1c7c: e5846038 str r6, [r4, #56] ; 0x38
clk = devm_clk_register(&client->dev, &drvdata->clkin);
1c80: e2841030 add r1, r4, #48 ; 0x30
1c84: e1a0000b mov r0, fp
1c88: ebfffffe bl 0 <devm_clk_register>
if (IS_ERR(clk)) {
1c8c: e3700a01 cmn r0, #4096 ; 0x1000
drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
init.parent_names = &drvdata->pclkin_name;
init.num_parents = 1;
}
drvdata->clkin.init = &init;
clk = devm_clk_register(&client->dev, &drvdata->clkin);
1c90: e1a05000 mov r5, r0
if (IS_ERR(clk)) {
1c94: 8afffe5d bhi 1610 <si5351_i2c_probe+0x61c>
goto err_clk;
}
}
/* Si5351C allows to mux either xtal or clkin to PLL input */
num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
1c98: e5943000 ldr r3, [r4]
1c9c: e3530004 cmp r3, #4
1ca0: 03a05002 moveq r5, #2
1ca4: 0afffdce beq 13e4 <si5351_i2c_probe+0x3f0>
1ca8: eafffdcc b 13e0 <si5351_i2c_probe+0x3ec>
init.flags = 0;
init.parent_names = parent_names;
init.num_parents = num_parents;
clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
if (IS_ERR(clk)) {
dev_err(&client->dev, "unable to register %s\n", init.name);
1cac: e3001000 movw r1, #0
1cb0: e1a0000b mov r0, fp
1cb4: e3401000 movt r1, #0
1cb8: e59d2034 ldr r2, [sp, #52] ; 0x34
1cbc: e1a05003 mov r5, r3
1cc0: ebfffffe bl 0 <dev_err>
ret = PTR_ERR(clk);
goto err_clk;
1cc4: eafffe56 b 1624 <si5351_i2c_probe+0x630>
ret);
}
}
}
ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
1cc8: e59d3004 ldr r3, [sp, #4]
1ccc: e3001000 movw r1, #0
1cd0: e1a0400b mov r4, fp
1cd4: e3401000 movt r1, #0
1cd8: e284200c add r2, r4, #12
1cdc: e59db00c ldr fp, [sp, #12]
1ce0: e5930204 ldr r0, [r3, #516] ; 0x204
1ce4: ebfffffe bl 0 <of_clk_add_provider>
&drvdata->onecell);
if (ret) {
1ce8: e2505000 subs r5, r0, #0
1cec: 0afffeff beq 18f0 <si5351_i2c_probe+0x8fc>
dev_err(&client->dev, "unable to add clk provider\n");
1cf0: e3001000 movw r1, #0
1cf4: e1a0000b mov r0, fp
1cf8: e3401000 movt r1, #0
1cfc: ebfffffe bl 0 <dev_err>
goto err_clk;
1d00: eafffe47 b 1624 <si5351_i2c_probe+0x630>
case 1:
pdata->clkout[num].multisynth_src =
SI5351_MULTISYNTH_SRC_VCO1;
break;
default:
dev_err(&client->dev,
1d04: e3001000 movw r1, #0
1d08: e1a0000b mov r0, fp
1d0c: e3401000 movt r1, #0
1d10: e59d3024 ldr r3, [sp, #36] ; 0x24
1d14: ebfffffe bl 0 <dev_err>
"invalid parent %d for multisynth %d\n",
val, num);
return -EINVAL;
1d18: e3e00015 mvn r0, #21
1d1c: eafffcfa b 110c <si5351_i2c_probe+0x118>
if (!of_property_read_u32(child, "silabs,multisynth-source",
&val)) {
switch (val) {
case 0:
pdata->clkout[num].multisynth_src =
1d20: e59d2024 ldr r2, [sp, #36] ; 0x24
1d24: e3a01001 mov r1, #1
1d28: e1a03282 lsl r3, r2, #5
1d2c: e0433182 sub r3, r3, r2, lsl #3
1d30: e0883003 add r3, r8, r3
1d34: e5831008 str r1, [r3, #8]
1d38: eaffff2a b 19e8 <si5351_i2c_probe+0x9f4>
if (np == NULL)
return 0;
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
1d3c: e3e0000b mvn r0, #11
1d40: eafffcf1 b 110c <si5351_i2c_probe+0x118>
if (ret)
return ret;
pdata = client->dev.platform_data;
if (!pdata)
return -EINVAL;
1d44: e3e00015 mvn r0, #21
1d48: eafffcef b 110c <si5351_i2c_probe+0x118>
}
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_CLKIN;
break;
default:
dev_err(&client->dev,
1d4c: e3001000 movw r1, #0
1d50: e1a0000b mov r0, fp
1d54: e3401000 movt r1, #0
1d58: e59d3024 ldr r3, [sp, #36] ; 0x24
1d5c: ebfffffe bl 0 <dev_err>
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
1d60: e3e00015 mvn r0, #21
1d64: eafffce8 b 110c <si5351_i2c_probe+0x118>
case 3:
pdata->clkout[num].disable_state =
SI5351_DISABLE_NEVER;
break;
default:
dev_err(&client->dev,
1d68: e3001000 movw r1, #0
1d6c: e1a0000b mov r0, fp
1d70: e3401000 movt r1, #0
1d74: e59d3024 ldr r3, [sp, #36] ; 0x24
1d78: ebfffffe bl 0 <dev_err>
"invalid disable state %d for clkout %d\n",
val, num);
return -EINVAL;
1d7c: e3e00015 mvn r0, #21
1d80: eafffce1 b 110c <si5351_i2c_probe+0x118>
if (!pdata)
return -EINVAL;
drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
if (drvdata == NULL) {
dev_err(&client->dev, "unable to allocate driver data\n");
1d84: e3001000 movw r1, #0
1d88: e1a0000b mov r0, fp
1d8c: e3401000 movt r1, #0
1d90: ebfffffe bl 0 <dev_err>
return -ENOMEM;
1d94: e3e0000b mvn r0, #11
1d98: eafffcdb b 110c <si5351_i2c_probe+0x118>
return -EINVAL;
}
if (num >= 8 ||
(variant == SI5351_VARIANT_A3 && num >= 3)) {
dev_err(&client->dev, "invalid clkout %d\n", num);
1d9c: e3001000 movw r1, #0
1da0: e1a0000b mov r0, fp
1da4: e3401000 movt r1, #0
1da8: ebfffffe bl 0 <dev_err>
return -EINVAL;
1dac: e3e00015 mvn r0, #21
1db0: eafffcd5 b 110c <si5351_i2c_probe+0x118>
}
/* per clkout properties */
for_each_child_of_node(np, child) {
if (of_property_read_u32(child, "reg", &num)) {
dev_err(&client->dev, "missing reg property of %s\n",
1db4: e3001000 movw r1, #0
1db8: e1a0000b mov r0, fp
1dbc: e5942000 ldr r2, [r4]
1dc0: e3401000 movt r1, #0
1dc4: ebfffffe bl 0 <dev_err>
child->name);
return -EINVAL;
1dc8: e3e00015 mvn r0, #21
1dcc: eafffcce b 110c <si5351_i2c_probe+0x118>
case SI5351_DRIVE_6MA:
case SI5351_DRIVE_8MA:
pdata->clkout[num].drive = val;
break;
default:
dev_err(&client->dev,
1dd0: e3001000 movw r1, #0
1dd4: e1a0000b mov r0, fp
1dd8: e3401000 movt r1, #0
1ddc: e59d3024 ldr r3, [sp, #36] ; 0x24
1de0: ebfffffe bl 0 <dev_err>
"invalid drive strength %d for clkout %d\n",
val, num);
return -EINVAL;
1de4: e3e00015 mvn r0, #21
1de8: eafffcc7 b 110c <si5351_i2c_probe+0x118>
pdata->clkout[num].clkout_src =
SI5351_CLKOUT_SRC_XTAL;
break;
case 3:
if (variant != SI5351_VARIANT_C) {
dev_err(&client->dev,
1dec: e3001000 movw r1, #0
1df0: e1a0000b mov r0, fp
1df4: e3401000 movt r1, #0
1df8: e59d3024 ldr r3, [sp, #36] ; 0x24
1dfc: e3a02003 mov r2, #3
1e00: ebfffffe bl 0 <dev_err>
"invalid parent %d for clkout %d\n",
val, num);
return -EINVAL;
1e04: e3e00015 mvn r0, #21
1e08: eafffcbf b 110c <si5351_i2c_probe+0x118>
1e0c: 00000034 .word 0x00000034
1e10: 000000ac .word 0x000000ac
1e14: 0000014c .word 0x0000014c
1e18: 000001ec .word 0x000001ec
1e1c: 0000020c .word 0x0000020c
1e20: 0000027c .word 0x0000027c
1e24: 000000fc .word 0x000000fc
00001e28 <si5351_msynth_set_parent>:
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e28: e3510000 cmp r1, #0
return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
}
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
1e2c: e92d4010 push {r4, lr}
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e30: e5d02020 ldrb r2, [r0, #32]
1e34: 1a000003 bne 1e48 <si5351_msynth_set_parent+0x20>
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e38: e3520008 cmp r2, #8
1e3c: da00000c ble 1e74 <si5351_msynth_set_parent+0x4c>
return -EINVAL;
1e40: e3e00015 mvn r0, #21
static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
1e44: e8bd8010 pop {r4, pc}
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e48: e3520008 cmp r2, #8
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1e4c: d2822010 addle r2, r2, #16
1e50: d3a03020 movle r3, #32
1e54: d6ef1072 uxtble r1, r2
int num, enum si5351_multisynth_src parent)
{
if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
return 0;
if (num > 8)
1e58: cafffff8 bgt 1e40 <si5351_msynth_set_parent+0x18>
}
static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
u8 reg, u8 mask, u8 val)
{
return regmap_update_bits(drvdata->regmap, reg, mask, val);
1e5c: e590000c ldr r0, [r0, #12]
1e60: e3a02020 mov r2, #32
1e64: e5900008 ldr r0, [r0, #8]
1e68: ebfffffe bl 0 <regmap_update_bits>
1e6c: e3a00000 mov r0, #0
1e70: e8bd8010 pop {r4, pc}
return 0;
if (num > 8)
return -EINVAL;
si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
1e74: e2822010 add r2, r2, #16
1e78: e1a03001 mov r3, r1
1e7c: e6ef1072 uxtb r1, r2
1e80: eafffff5 b 1e5c <si5351_msynth_set_parent+0x34>
1e84: e320f000 nop {0}
Disassembly of section .init.text:
00000000 <si5351_driver_init>:
}
}
static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
0: e3001000 movw r1, #0
4: e3a00000 mov r0, #0
8: e3401000 movt r1, #0
c: eafffffe b 0 <i2c_register_driver>
Disassembly of section .exit.text:
00000000 <si5351_driver_exit>:
0: e3000000 movw r0, #0
4: e3400000 movt r0, #0
8: eafffffe b 0 <i2c_del_driver>
More information about the Openembedded-devel
mailing list