Skip to content

Commit 6262758

Browse files
committed
iio: frequency: adf41513: expose clk interface
Clock framework integration as a clock provider to expose the output signal for use by other kernel subsystems Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
1 parent b6bbd82 commit 6262758

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

drivers/iio/frequency/adf41513.c

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/bitfield.h>
99
#include <linux/bits.h>
1010
#include <linux/clk.h>
11+
#include <linux/clk-provider.h>
1112
#include <linux/device.h>
1213
#include <linux/err.h>
1314
#include <linux/gpio/consumer.h>
@@ -252,6 +253,8 @@ struct adf41513_state {
252253
struct gpio_desc *lock_detect;
253254
struct gpio_desc *chip_enable;
254255
struct clk *ref_clk;
256+
struct clk *clk_out;
257+
struct clk_hw clk_hw;
255258

256259
u64 ref_freq_hz;
257260

@@ -281,6 +284,8 @@ struct adf41513_state {
281284
__be32 buf __aligned(IIO_DMA_MINALIGN);
282285
};
283286

287+
#define to_adf41513_state(_hw) container_of(_hw, struct adf41513_state, clk_hw)
288+
284289
static const u16 adf41513_ld_window_p1ns[] = {
285290
9, 12, 16, 17, 21, 28, 29, 35, /* 0 - 7 */
286291
43, 47, 49, 52, 70, 79, 115 /* 8 - 14 */
@@ -1126,6 +1131,148 @@ static const struct iio_info adf41513_info = {
11261131
.debugfs_reg_access = &adf41513_reg_access,
11271132
};
11281133

1134+
static void adf41513_clk_del_provider(void *data)
1135+
{
1136+
struct adf41513_state *st = data;
1137+
1138+
of_clk_del_provider(st->spi->dev.of_node);
1139+
}
1140+
1141+
static unsigned long adf41513_clk_recalc_rate(struct clk_hw *hw,
1142+
unsigned long parent_rate)
1143+
{
1144+
struct adf41513_state *st = to_adf41513_state(hw);
1145+
1146+
guard(mutex)(&st->lock);
1147+
return div_u64(adf41513_pll_get_rate(st), MICROHZ_PER_HZ);
1148+
}
1149+
1150+
static long adf41513_clk_round_rate(struct clk_hw *hw,
1151+
unsigned long rate,
1152+
unsigned long *parent_rate)
1153+
{
1154+
return rate;
1155+
}
1156+
1157+
static int adf41513_clk_set_rate(struct clk_hw *hw,
1158+
unsigned long rate,
1159+
unsigned long parent_rate)
1160+
{
1161+
struct adf41513_state *st = to_adf41513_state(hw);
1162+
u64 freq_uhz = (u64)rate * MICROHZ_PER_HZ;
1163+
1164+
if (parent_rate < ADF41513_MIN_REF_FREQ ||
1165+
parent_rate > ADF41513_MAX_REF_FREQ)
1166+
return -EINVAL;
1167+
1168+
guard(mutex)(&st->lock);
1169+
st->ref_freq_hz = parent_rate;
1170+
return adf41513_set_frequency(st, freq_uhz, ADF41513_SYNC_DIFF);
1171+
}
1172+
1173+
static int adf41513_clk_prepare(struct clk_hw *hw)
1174+
{
1175+
struct adf41513_state *st = to_adf41513_state(hw);
1176+
1177+
guard(mutex)(&st->lock);
1178+
return adf41513_resume(st);
1179+
}
1180+
1181+
static void adf41513_clk_unprepare(struct clk_hw *hw)
1182+
{
1183+
struct adf41513_state *st = to_adf41513_state(hw);
1184+
1185+
guard(mutex)(&st->lock);
1186+
adf41513_suspend(st);
1187+
}
1188+
1189+
static int adf41513_clk_is_enabled(struct clk_hw *hw)
1190+
{
1191+
struct adf41513_state *st = to_adf41513_state(hw);
1192+
1193+
guard(mutex)(&st->lock);
1194+
return (st->regs_hw[ADF41513_REG6] & ADF41513_REG6_POWER_DOWN_MSK) == 0;
1195+
}
1196+
1197+
static int adf41513_clk_get_phase(struct clk_hw *hw)
1198+
{
1199+
struct adf41513_state *st = to_adf41513_state(hw);
1200+
u32 phase_val;
1201+
1202+
phase_val = FIELD_GET(ADF41513_REG2_PHASE_VAL_MSK, st->regs_hw[ADF41513_REG2]);
1203+
return DIV_ROUND_CLOSEST(360 * phase_val, BIT(12));
1204+
}
1205+
1206+
static int adf41513_clk_set_phase(struct clk_hw *hw, int degrees)
1207+
{
1208+
struct adf41513_state *st = to_adf41513_state(hw);
1209+
u32 phase_val;
1210+
1211+
degrees %= 360;
1212+
if (degrees < 0)
1213+
degrees += 360;
1214+
phase_val = DIV_ROUND_CLOSEST(degrees << 12, 360);
1215+
1216+
guard(mutex)(&st->lock);
1217+
1218+
st->regs[ADF41513_REG2] |= ADF41513_REG2_PHASE_ADJ_MSK;
1219+
st->regs[ADF41513_REG2] &= ~ADF41513_REG2_PHASE_VAL_MSK;
1220+
st->regs[ADF41513_REG2] |= FIELD_PREP(ADF41513_REG2_PHASE_VAL_MSK, phase_val);
1221+
return adf41513_sync_config(st, ADF41513_SYNC_REG0);
1222+
}
1223+
1224+
static const struct clk_ops adf41513_clk_ops = {
1225+
.recalc_rate = adf41513_clk_recalc_rate,
1226+
.round_rate = adf41513_clk_round_rate,
1227+
.set_rate = adf41513_clk_set_rate,
1228+
.prepare = adf41513_clk_prepare,
1229+
.unprepare = adf41513_clk_unprepare,
1230+
.is_enabled = adf41513_clk_is_enabled,
1231+
.get_phase = adf41513_clk_get_phase,
1232+
.set_phase = adf41513_clk_set_phase,
1233+
};
1234+
1235+
static int adf41513_clk_register(struct adf41513_state *st)
1236+
{
1237+
struct spi_device *spi = st->spi;
1238+
struct clk_init_data init;
1239+
struct clk *clk = NULL;
1240+
const char *parent_name;
1241+
int ret;
1242+
1243+
if (!device_property_present(&spi->dev, "#clock-cells"))
1244+
return 0;
1245+
1246+
if (device_property_read_string(&spi->dev, "clock-output-names", &init.name)) {
1247+
init.name = devm_kasprintf(&spi->dev, GFP_KERNEL, "%s-clk",
1248+
fwnode_get_name(dev_fwnode(&spi->dev)));
1249+
if (!init.name)
1250+
return -ENOMEM;
1251+
}
1252+
1253+
parent_name = of_clk_get_parent_name(spi->dev.of_node, 0);
1254+
if (!parent_name)
1255+
return -EINVAL;
1256+
1257+
init.ops = &adf41513_clk_ops;
1258+
init.parent_names = &parent_name;
1259+
init.num_parents = 1;
1260+
init.flags = CLK_SET_RATE_PARENT;
1261+
1262+
st->clk_hw.init = &init;
1263+
clk = devm_clk_register(&spi->dev, &st->clk_hw);
1264+
if (IS_ERR(clk))
1265+
return PTR_ERR(clk);
1266+
1267+
ret = of_clk_add_provider(spi->dev.of_node, of_clk_src_simple_get, clk);
1268+
if (ret)
1269+
return ret;
1270+
1271+
st->clk_out = clk;
1272+
1273+
return devm_add_action_or_reset(&spi->dev, adf41513_clk_del_provider, st);
1274+
}
1275+
11291276
static int adf41513_parse_fw(struct adf41513_state *st)
11301277
{
11311278
struct device *dev = &st->spi->dev;
@@ -1343,6 +1490,10 @@ static int adf41513_probe(struct spi_device *spi)
13431490
if (ret < 0)
13441491
return dev_err_probe(&spi->dev, ret, "failed to setup device: %d\n", ret);
13451492

1493+
ret = adf41513_clk_register(st);
1494+
if (ret < 0)
1495+
return dev_err_probe(&spi->dev, ret, "failed to register clock: %d\n", ret);
1496+
13461497
ret = devm_add_action_or_reset(&spi->dev, adf41513_power_down, st);
13471498
if (ret)
13481499
return dev_err_probe(&spi->dev, ret, "Failed to add power down action: %d\n", ret);

0 commit comments

Comments
 (0)