Skip to content

Commit

Permalink
at86rf230: add support for external xtal trim
Browse files Browse the repository at this point in the history
This patch adds support for setting the xtal trim register. Some at86rf2xx
transceiver boards needs fine tuning the xtal capacitor.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Alexander Aring authored and Marcel Holtmann committed Feb 27, 2015
1 parent aaa1c4d commit ccdaeb2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Required properties:
Optional properties:
- reset-gpio: GPIO spec for the rstn pin
- sleep-gpio: GPIO spec for the slp_tr pin
- xtal-trim: u8 value for fine tuning the internal capacitance
arrays of xtal pins: 0 = +0 pF, 0xf = +4.5 pF

Example:

Expand All @@ -20,4 +22,5 @@ Example:
reg = <0>;
interrupts = <19 1>;
interrupt-parent = <&gpio3>;
xtal-trim = /bits/ 8 <0x06>;
};
54 changes: 50 additions & 4 deletions drivers/net/ieee802154/at86rf230.c
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ static struct at86rf2xx_chip_data at86rf212_data = {
.get_desense_steps = at86rf212_get_desens_steps
};

static int at86rf230_hw_init(struct at86rf230_local *lp)
static int at86rf230_hw_init(struct at86rf230_local *lp, u8 xtal_trim)
{
int rc, irq_type, irq_pol = IRQ_ACTIVE_HIGH;
unsigned int dvdd;
Expand Down Expand Up @@ -1362,6 +1362,45 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
usleep_range(lp->data->t_sleep_cycle,
lp->data->t_sleep_cycle + 100);

/* xtal_trim value is calculated by:
* CL = 0.5 * (CX + CTRIM + CPAR)
*
* whereas:
* CL = capacitor of used crystal
* CX = connected capacitors at xtal pins
* CPAR = in all at86rf2xx datasheets this is a constant value 3 pF,
* but this is different on each board setup. You need to fine
* tuning this value via CTRIM.
* CTRIM = variable capacitor setting. Resolution is 0.3 pF range is
* 0 pF upto 4.5 pF.
*
* Examples:
* atben transceiver:
*
* CL = 8 pF
* CX = 12 pF
* CPAR = 3 pF (We assume the magic constant from datasheet)
* CTRIM = 0.9 pF
*
* (12+0.9+3)/2 = 7.95 which is nearly at 8 pF
*
* xtal_trim = 0x3
*
* openlabs transceiver:
*
* CL = 16 pF
* CX = 22 pF
* CPAR = 3 pF (We assume the magic constant from datasheet)
* CTRIM = 4.5 pF
*
* (22+4.5+3)/2 = 14.75 which is the nearest value to 16 pF
*
* xtal_trim = 0xf
*/
rc = at86rf230_write_subreg(lp, SR_XTAL_TRIM, xtal_trim);
if (rc)
return rc;

rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd);
if (rc)
return rc;
Expand All @@ -1378,21 +1417,27 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
}

static int
at86rf230_get_pdata(struct spi_device *spi, int *rstn, int *slp_tr)
at86rf230_get_pdata(struct spi_device *spi, int *rstn, int *slp_tr,
u8 *xtal_trim)
{
struct at86rf230_platform_data *pdata = spi->dev.platform_data;
int ret;

if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node) {
if (!pdata)
return -ENOENT;

*rstn = pdata->rstn;
*slp_tr = pdata->slp_tr;
*xtal_trim = pdata->xtal_trim;
return 0;
}

*rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
*slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
ret = of_property_read_u8(spi->dev.of_node, "xtal-trim", xtal_trim);
if (ret < 0 && ret != -EINVAL)
return ret;

return 0;
}
Expand Down Expand Up @@ -1505,13 +1550,14 @@ static int at86rf230_probe(struct spi_device *spi)
struct at86rf230_local *lp;
unsigned int status;
int rc, irq_type, rstn, slp_tr;
u8 xtal_trim;

if (!spi->irq) {
dev_err(&spi->dev, "no IRQ specified\n");
return -EINVAL;
}

rc = at86rf230_get_pdata(spi, &rstn, &slp_tr);
rc = at86rf230_get_pdata(spi, &rstn, &slp_tr, &xtal_trim);
if (rc < 0) {
dev_err(&spi->dev, "failed to parse platform_data: %d\n", rc);
return rc;
Expand Down Expand Up @@ -1570,7 +1616,7 @@ static int at86rf230_probe(struct spi_device *spi)

spi_set_drvdata(spi, lp);

rc = at86rf230_hw_init(lp);
rc = at86rf230_hw_init(lp, xtal_trim);
if (rc)
goto free_dev;

Expand Down
1 change: 1 addition & 0 deletions include/linux/spi/at86rf230.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct at86rf230_platform_data {
int rstn;
int slp_tr;
int dig2;
u8 xtal_trim;
};

#endif

0 comments on commit ccdaeb2

Please sign in to comment.