blob: da1e7f24469f01859bfe81e9bf0bc764be3b55b7 [file] [log] [blame]
Sylvain Munautcaf8cf92022-01-12 13:35:12 +01001/*
2 * usb_dev.c
3 *
4 * Copyright (C) 2019-2022 Sylvain Munaut <tnt@246tNt.com>
5 * SPDX-License-Identifier: GPL-3.0-or-later
6 */
7
8#include <stdint.h>
Sylvain Munaut2c33f6d2022-01-12 14:12:31 +01009#include <string.h>
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010010
11#include <no2usb/usb.h>
12#include <no2usb/usb_proto.h>
13
14#include "console.h"
Sylvain Munaut09dc0372022-10-05 12:39:54 +020015#include "i2c.h"
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010016#include "misc.h"
17
18#include "ice1usb_proto.h"
19
20
Sylvain Munaut2c33f6d2022-01-12 14:12:31 +010021const char *fw_build_str = BUILD_INFO;
22
23
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010024static enum usb_fnd_resp
Sylvain Munautb722de72022-10-05 12:39:21 +020025_usb_dev_ctrl_req_write(struct usb_ctrl_req *req, struct usb_xfer *xfer)
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010026{
Sylvain Munautb722de72022-10-05 12:39:21 +020027 switch (req->bRequest) {
Sylvain Munaut09dc0372022-10-05 12:39:54 +020028 case ICE1USB_DEV_I2C_REG_ACCESS:
29 if (!i2c_write_reg((req->wIndex >> 8), req->wIndex & 0xff, req->wValue & 0xff))
30 return USB_FND_ERROR;
31 break;
Sylvain Munautb722de72022-10-05 12:39:21 +020032 default:
33 return USB_FND_ERROR;
34 }
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010035
Sylvain Munautb722de72022-10-05 12:39:21 +020036 return USB_FND_SUCCESS;
37}
38
39static enum usb_fnd_resp
40_usb_dev_ctrl_req_read(struct usb_ctrl_req *req, struct usb_xfer *xfer)
41{
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010042 switch (req->bRequest) {
43 case ICE1USB_DEV_GET_CAPABILITIES:
44 xfer->data[0] = (1 << ICE1USB_DEV_CAP_GPSDO);
45 xfer->len = 1;
46 break;
Sylvain Munaut2c33f6d2022-01-12 14:12:31 +010047 case ICE1USB_DEV_GET_FW_BUILD:
48 xfer->data = (void*) fw_build_str;
49 xfer->len = strlen(fw_build_str);
50 break;
Sylvain Munaut09dc0372022-10-05 12:39:54 +020051 case ICE1USB_DEV_I2C_REG_ACCESS:
52 if (!i2c_read_reg((req->wIndex >> 8), req->wIndex & 0xff, &xfer->data[0]))
53 return USB_FND_ERROR;
54 xfer->len = 1;
55 break;
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010056 default:
57 return USB_FND_ERROR;
58 }
59
60 return USB_FND_SUCCESS;
61}
62
Sylvain Munautb722de72022-10-05 12:39:21 +020063static enum usb_fnd_resp
64_usb_dev_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
65{
66 /* Check it's a device-wide vendor request */
67 if (USB_REQ_TYPE_RCPT(req) != (USB_REQ_TYPE_VENDOR | USB_REQ_RCPT_DEV))
68 return USB_FND_CONTINUE;
69
70 /* Read / Write dispatch */
71 if (USB_REQ_IS_READ(req))
72 return _usb_dev_ctrl_req_read(req, xfer);
73 else
74 return _usb_dev_ctrl_req_write(req, xfer);
75}
76
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010077
78static struct usb_fn_drv _dev_drv = {
79 .ctrl_req = _usb_dev_ctrl_req,
80};
81
82void
83usb_dev_init(void)
84{
85 usb_register_function_driver(&_dev_drv);
86}