90 lines
2.7 KiB
C
90 lines
2.7 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
#ifndef __LINUX_USB_DAPPERMIMEJTAG_H
|
||
|
#define __LINUX_USB_DAPPERMIMEJTAG_H
|
||
|
|
||
|
#define DP_USB_CFG_PROTO_VER 0x0010
|
||
|
|
||
|
#define DP_RESP_STAT_OK 0x00
|
||
|
#define DP_RESP_STAT_ILLCMD 0x01
|
||
|
#define DP_RESP_STAT_BADMODE 0x02
|
||
|
#define DP_RESP_STAT_NOSUCHMODE 0x03
|
||
|
#define DP_RESP_STAT_BADARG 0x04
|
||
|
#define DP_RESP_STAT_ILLSTATE 0x05
|
||
|
|
||
|
#define DP_CMD_CFG_GET_VERSION 0x00
|
||
|
#define DP_CMD_CFG_GET_MODES 0x01
|
||
|
#define DP_CMD_CFG_GET_CUR_MODE 0x02
|
||
|
#define DP_CMD_CFG_SET_CUR_MODE 0x03
|
||
|
#define DP_CMD_CFG_GET_INFOSTR 0x04
|
||
|
|
||
|
#define DP_CMD_MODE_GET_NAME 0x00
|
||
|
#define DP_CMD_MODE_GET_VERSION 0x01
|
||
|
#define DP_CMD_MODE_GET_FEATURES 0x02
|
||
|
|
||
|
#define DP_CMD_MODE1_SPI 0x13
|
||
|
#define DP_CMD_MODE1_I2C 0x14
|
||
|
#define DP_CMD_MODE1_TEMPSENSOR 0x15
|
||
|
|
||
|
#define DP_FEATURE_MODE1_UART (1<<0)
|
||
|
#define DP_FEATURE_MODE1_CMSISDAP (1<<1)
|
||
|
#define DP_FEATURE_MODE1_SPI (1<<2)
|
||
|
#define DP_FEATURE_MODE1_I2C (1<<3)
|
||
|
#define DP_FEATURE_MODE1_TEMPSENSOR (1<<4)
|
||
|
|
||
|
#define DP_XFER_FLAGS_PARSE_RESP (1<<0)
|
||
|
#define DP_XFER_FLAGS_FILL_RECVBUF (1<<1)
|
||
|
|
||
|
inline static const char *dp_get_protoerr(int err)
|
||
|
{
|
||
|
switch (err) {
|
||
|
case DP_RESP_STAT_OK: return "ok";
|
||
|
case DP_RESP_STAT_ILLCMD: return "unknown/unimplemented command";
|
||
|
case DP_RESP_STAT_BADMODE: return "bad mode";
|
||
|
case DP_RESP_STAT_NOSUCHMODE: return "no such mode available";
|
||
|
case DP_RESP_STAT_BADARG: return "illegal argument";
|
||
|
case DP_RESP_STAT_ILLSTATE: return "wrong state for command";
|
||
|
default: return "???";
|
||
|
}
|
||
|
}
|
||
|
inline static int dp_check_retval(int ret, int len, struct device *dev,
|
||
|
const char *pfix, bool check_pos_val, int lmin, int lmax)
|
||
|
{
|
||
|
if (ret < 0) {
|
||
|
dev_err(dev, "%s: USB fail: %d\n", pfix, ret);
|
||
|
return ret;
|
||
|
}
|
||
|
if (ret && check_pos_val) {
|
||
|
dev_err(dev, "%s: USB protocol fail: %s (%d)\n", pfix, dp_get_protoerr(ret), ret);
|
||
|
return -EIO;
|
||
|
}
|
||
|
if (len < lmin && lmin >= 0) {
|
||
|
dev_err(dev, "%s: USB reply too short: %d\n", pfix, len);
|
||
|
return -EREMOTEIO;
|
||
|
}
|
||
|
if (len > lmax && lmax >= 0) {
|
||
|
dev_err(dev, "%s: USB reply too long: %d\n", pfix, len);
|
||
|
return -EMSGSIZE;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* TODO: split up in "raw" read & writes, and higher-level ones with cmd and
|
||
|
* repstat, because the way this is currently overloaded, is, bad */
|
||
|
int dp_transfer(struct platform_device *pdev, int cmd, int recvflags,
|
||
|
const void *wbuf, int wbufsize, void **rbuf, int *rbufsize);
|
||
|
|
||
|
inline static int dp_read(struct platform_device *pdev, int recvflags,
|
||
|
void **rbuf, int *rbufsize)
|
||
|
{
|
||
|
return dp_transfer(pdev, -1, recvflags, NULL, 0, rbuf, rbufsize);
|
||
|
}
|
||
|
|
||
|
inline static int dp_write(struct platform_device *pdev, int cmd,
|
||
|
const void *wbuf, int wbufsize)
|
||
|
{
|
||
|
return dp_transfer(pdev, cmd, DP_XFER_FLAGS_PARSE_RESP, wbuf, wbufsize, NULL, NULL);
|
||
|
}
|
||
|
|
||
|
#endif
|