Skip to content

Commit

Permalink
iio: adc: ad9361: adjust RX/TX port selection based on during band se…
Browse files Browse the repository at this point in the history
…ttings

The RX/TX port must also be adjusted for certain settings.
This change adds support for specifying and changing port selection based
on external band settings.

Each setting can also specify RF input & output ports to be selected
by specifying the `adi,rx-rf-port-input-select` and
`adi,tx-rf-port-input-select` options.

Example:
	adi_rx_band_setting_0 {
		adi,lo-freq-min = /bits/ 64 <50000000>;
		adi,lo-freq-max = /bits/ 64 <435000000>;
		adi,rx-rf-port-input-select = <2>;
	};

Values are the same as described in the `RF Port Control` section of the
DT document. GPIO values can be omitted.
These values can be assigned to any recursed sub-setting to take advantage
of setting sequencing.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
  • Loading branch information
commodo committed May 17, 2018
1 parent dedf3e3 commit 59bf8f4
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
18 changes: 18 additions & 0 deletions Documentation/devicetree/bindings/iio/adc/adi,ad9361.txt
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,24 @@ External Filter Banks Control via GPIO
The driver should pick up if there is an infinite recursion in the call
hierarchy, as each setting node can call other setting nodes.

4. Controlling AD9361 Input/Output ports

Each setting can also specify RF input & output ports to be selected
by specifying the `adi,rx-rf-port-input-select` and
`adi,tx-rf-port-input-select` options.

Example:
adi_rx_band_setting_0 {
adi,lo-freq-min = /bits/ 64 <50000000>;
adi,lo-freq-max = /bits/ 64 <435000000>;
adi,rx-rf-port-input-select = <2>;
};

Values are the same as described in the `RF Port Control` section
of this document. GPIO values can be omitted.
These values can be assigned to any recursed sub-setting
to take advantage of setting sequencing.

Example:
&spi0 {
status = "okay";
Expand Down
87 changes: 87 additions & 0 deletions drivers/iio/adc/ad9361_ext_band_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ struct ad9361_band_setting {
u64 freq_min;
u64 freq_max;
u32 *gpio_values;
u32 rf_rx_input_sel;
u32 rf_tx_output_sel;

/* reference to the global objects to be controlled;
* to number of args in some calls
*/
Expand Down Expand Up @@ -185,6 +188,30 @@ static int ad9361_parse_setting_seq(struct device *dev,
return rc;
}

static int ad9361_parse_platform_data(struct ad9361_band_setting *sett,
struct device *dev,
struct device_node *np)
{
int ret;
u32 val;

ret = of_property_read_u32(np, "adi,rx-rf-port-input-select", &val);
if (ret == 0) {
dev_dbg(dev, " * adi,rx-rf-port-input-select: %u\n", val);
sett->rf_rx_input_sel = val;
} else
sett->rf_rx_input_sel = NO_PORT_SEL;

ret = of_property_read_u32(np, "adi,tx-rf-port-input-select", &val);
if (ret == 0) {
dev_dbg(dev, " * adi,tx-rf-port-input-select: %u\n", val);
sett->rf_tx_output_sel = val;
} else
sett->rf_tx_output_sel = NO_PORT_SEL;

return 0;
}

static int ad9361_parse_gpio_settings(struct device *dev,
struct device_node *np,
struct ad9361_ext_band_ctl *ctl,
Expand Down Expand Up @@ -275,6 +302,10 @@ static int ad9361_parse_setting(struct device *dev,
if (ret < 0)
return ret;

ret = ad9361_parse_platform_data(sett, dev, np);
if (ret < 0)
return ret;

ret = ad9361_parse_setting_seq(dev, np, "adi,band-ctl-post", ctl,
&sett->post, root_node_name);
if (ret < 0)
Expand Down Expand Up @@ -535,6 +566,54 @@ static int ad9361_apply_gpio_settings(struct device *dev,
return 0;
}

static int ad9361_apply_rx_port_settings(struct ad9361_rf_phy *phy,
struct ad9361_band_setting *new,
struct ad9361_band_setting *curr)
{
struct device *dev = &phy->spi->dev;
int ret;

if (new->rf_rx_input_sel == NO_PORT_SEL)
return 0;

if (curr &&
new->rf_rx_input_sel == curr->rf_rx_input_sel)
return 0;

ret = ad9361_set_rx_port(phy, new->rf_rx_input_sel);
if (ret < 0)
dev_err(dev, "%s: got error for RX input sel %d\n", __func__, ret);
else
dev_dbg(dev, "%s: RX input sel %u\n", __func__,
new->rf_rx_input_sel);

return ret;
}

static int ad9361_apply_tx_port_settings(struct ad9361_rf_phy *phy,
struct ad9361_band_setting *new,
struct ad9361_band_setting *curr)
{
struct device *dev = &phy->spi->dev;
int ret;

if (new->rf_tx_output_sel == NO_PORT_SEL)
return 0;

if (curr &&
new->rf_tx_output_sel == curr->rf_tx_output_sel)
return 0;

ret = ad9361_set_tx_port(phy, new->rf_tx_output_sel);
if (ret < 0)
dev_err(dev, "%s: got error for TX output sel %d\n", __func__, ret);
else
dev_dbg(dev, "%s: TX output sel %u\n", __func__,
new->rf_tx_output_sel);

return ret;
}

static int ad9361_apply_settings(struct ad9361_rf_phy *phy,
struct ad9361_band_setting *new,
struct ad9361_band_setting **curr)
Expand Down Expand Up @@ -563,6 +642,14 @@ static int ad9361_apply_settings(struct ad9361_rf_phy *phy,
if (ret < 0)
return ret;

ret = ad9361_apply_rx_port_settings(phy, new, lcurr);
if (ret < 0)
return ret;

ret = ad9361_apply_tx_port_settings(phy, new, lcurr);
if (ret < 0)
return ret;

*curr = new;
if (!list_empty(&new->post)) {
ret = ad9361_apply_settings_seq(phy, &new->post, curr);
Expand Down

0 comments on commit 59bf8f4

Please sign in to comment.