From: "Radek Dostál" <radek.dostal@streamunlimited.com>
To: openembedded-devel@lists.openembedded.org
Subject: GCC5.2 causing bug in si5351 kernel driver
Date: Wed, 28 Oct 2015 19:28:08 +0100 [thread overview]
Message-ID: <563113B8.2030106@streamunlimited.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 920 bytes --]
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
[-- Attachment #2: workaround.diff --]
[-- Type: text/x-patch, Size: 505 bytes --]
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
index 30335d3..dffea95 100644
--- a/drivers/clk/clk-si5351.c
+++ b/drivers/clk/clk-si5351.c
@@ -735,6 +735,7 @@ static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
"%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);
return rate;
}
[-- Attachment #3: without-workaround --]
[-- Type: text/plain, Size: 179938 bytes --]
./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>
[-- Attachment #4: with-workaround --]
[-- Type: text/plain, Size: 179823 bytes --]
./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>
reply other threads:[~2015-10-28 18:28 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=563113B8.2030106@streamunlimited.com \
--to=radek.dostal@streamunlimited.com \
--cc=openembedded-devel@lists.openembedded.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.