aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ieee802154/atusb.c
diff options
context:
space:
mode:
authorStefan Schmidt <s.schmidt@samsung.com>2015-05-29 10:51:25 +0200
committerMarcel Holtmann <marcel@holtmann.org>2015-05-31 13:40:53 +0200
commitbdc78737278ee77fdcbccaee5b6f7eda4e0e7602 (patch)
tree77100c4b174f7389dc90bffa650e9faa1b185e4d /drivers/net/ieee802154/atusb.c
parentieee802154: Fix EUI-64 station address validation. (diff)
downloadlinux-dev-bdc78737278ee77fdcbccaee5b6f7eda4e0e7602.tar.xz
linux-dev-bdc78737278ee77fdcbccaee5b6f7eda4e0e7602.zip
ieee802154/atusb: Add function for partial register writes
With this function we can set individual bits in the registers if needed. With the old SR_VALUE macro we could only set one bit in the register which was ok for some scenarios but not for all. With this subreg write function we can now set more bits defined by the mask while not touching the rest. We start using it for the current SR_VALUE use case and will use it more in upcoming patches. Signed-off-by: Stefan Schmidt <stefan@osg.samsung.com> Reviewed-by: Varka Bhadram <varkabhadram@gmail.com> Acked-by: Alexander Aring <alex.aring@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/net/ieee802154/atusb.c')
-rw-r--r--drivers/net/ieee802154/atusb.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c
index 5b6bb9adf9ae..95d42205fd53 100644
--- a/drivers/net/ieee802154/atusb.c
+++ b/drivers/net/ieee802154/atusb.c
@@ -58,17 +58,6 @@ struct atusb {
uint8_t tx_ack_seq; /* current TX ACK sequence number */
};
-/* at86rf230.h defines values as <reg, mask, shift> tuples. We use the more
- * traditional style of having registers and or-able values. SR_REG extracts
- * the register number. SR_VALUE uses the shift to prepare a value accordingly.
- */
-
-#define __SR_REG(reg, mask, shift) (reg)
-#define SR_REG(sr) __SR_REG(sr)
-
-#define __SR_VALUE(reg, mask, shift, val) ((val) << (shift))
-#define SR_VALUE(sr, val) __SR_VALUE(sr, (val))
-
/* ----- USB commands without data ----------------------------------------- */
/* To reduce the number of error checks in the code, we record the first error
@@ -130,6 +119,30 @@ static int atusb_read_reg(struct atusb *atusb, uint8_t reg)
return ret >= 0 ? value : ret;
}
+static int atusb_write_subreg(struct atusb *atusb, uint8_t reg, uint8_t mask,
+ uint8_t shift, uint8_t value)
+{
+ struct usb_device *usb_dev = atusb->usb_dev;
+ uint8_t orig, tmp;
+ int ret = 0;
+
+ dev_dbg(&usb_dev->dev, "atusb_write_subreg: 0x%02x <- 0x%02x\n",
+ reg, value);
+
+ orig = atusb_read_reg(atusb, reg);
+
+ /* Write the value only into that part of the register which is allowed
+ * by the mask. All other bits stay as before.
+ */
+ tmp = orig & ~mask;
+ tmp |= (value << shift) & mask;
+
+ if (tmp != orig)
+ ret = atusb_write_reg(atusb, reg, tmp);
+
+ return ret;
+}
+
static int atusb_get_and_clear_error(struct atusb *atusb)
{
int err = atusb->err;
@@ -376,7 +389,6 @@ static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
{
struct atusb *atusb = hw->priv;
struct device *dev = &atusb->usb_dev->dev;
- uint8_t reg;
if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
u16 addr = le16_to_cpu(filt->short_addr);
@@ -406,12 +418,10 @@ static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw,
if (changed & IEEE802154_AFILT_PANC_CHANGED) {
dev_vdbg(dev,
"atusb_set_hw_addr_filt called for panc change\n");
- reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD));
if (filt->pan_coord)
- reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1);
+ atusb_write_subreg(atusb, SR_AACK_I_AM_COORD, 1);
else
- reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1);
- atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg);
+ atusb_write_subreg(atusb, SR_AACK_I_AM_COORD, 0);
}
return atusb_get_and_clear_error(atusb);
@@ -622,8 +632,7 @@ static int atusb_probe(struct usb_interface *interface,
* http://www.jennic.com/download_file.php?supportFile=JN-AN-1035%20Calculating%20802-15-4%20Data%20Rates-1v0.pdf
*/
- atusb_write_reg(atusb,
- SR_REG(SR_RX_SAFE_MODE), SR_VALUE(SR_RX_SAFE_MODE, 1));
+ atusb_write_subreg(atusb, SR_RX_SAFE_MODE, 1);
#endif
atusb_write_reg(atusb, RG_IRQ_MASK, 0xff);