blob: 2997a3388cb58d429b02493109c2bc8a097d01de [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 Munautc3083342022-01-13 00:50:10 +010015#include "gpsdo.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 Munautc3083342022-01-13 00:50:10 +010024static void
25_get_gpsdo_status(struct usb_ctrl_req *req, struct usb_xfer *xfer)
26{
27 struct e1usb_gpsdo_status status;
28
29 gpsdo_get_status(&status);
30
31 memcpy(xfer->data, &status, sizeof(struct e1usb_gpsdo_status));
32 xfer->len = sizeof(struct e1usb_gpsdo_status);
33}
34
35static void
36_get_gpsdo_mode(struct usb_ctrl_req *req, struct usb_xfer *xfer)
37{
38 xfer->data[0] = gpsdo_enabled() ? ICE1USB_GPSDO_MODE_DISABLED : ICE1USB_GPSDO_MODE_AUTO;
39 xfer->len = 1;
40}
41
42static void
43_set_gpsdo_mode(struct usb_ctrl_req *req, struct usb_xfer *xfer)
44{
45 gpsdo_enable(req->wValue != ICE1USB_GPSDO_MODE_DISABLED);
46}
47
48static void
49_get_gpsdo_tune(struct usb_ctrl_req *req, struct usb_xfer *xfer)
50{
51 uint16_t coarse, fine;
52 struct e1usb_gpsdo_tune tune;
53
54 gpsdo_get_tune(&coarse, &fine);
55 tune.coarse = coarse;
56 tune.fine = fine;
57
58 memcpy(xfer->data, &tune, sizeof(struct e1usb_gpsdo_tune));
59 xfer->len = sizeof(struct e1usb_gpsdo_tune);
60}
61
62static bool
63_set_gpsdo_tune_done(struct usb_xfer *xfer)
64{
65 const struct e1usb_gpsdo_tune *tune = (const void *) xfer->data;
66 gpsdo_set_tune(tune->coarse, tune->fine);
67 return true;
68}
69
70static void
71_set_gpsdo_tune(struct usb_ctrl_req *req, struct usb_xfer *xfer)
72{
73 xfer->cb_done = _set_gpsdo_tune_done;
74 xfer->cb_ctx = req;
75 xfer->len = sizeof(struct e1usb_gpsdo_tune);
76}
77
78
Sylvain Munautcaf8cf92022-01-12 13:35:12 +010079static enum usb_fnd_resp
80_usb_dev_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
81{
82 /* Check it's a device-wide vendor request */
83 if (USB_REQ_TYPE_RCPT(req) != (USB_REQ_TYPE_VENDOR | USB_REQ_RCPT_DEV))
84 return USB_FND_CONTINUE;
85
86 /* Dispatch / Handle */
87 switch (req->bRequest) {
88 case ICE1USB_DEV_GET_CAPABILITIES:
89 xfer->data[0] = (1 << ICE1USB_DEV_CAP_GPSDO);
90 xfer->len = 1;
91 break;
Sylvain Munaut2c33f6d2022-01-12 14:12:31 +010092 case ICE1USB_DEV_GET_FW_BUILD:
93 xfer->data = (void*) fw_build_str;
94 xfer->len = strlen(fw_build_str);
95 break;
Sylvain Munautc3083342022-01-13 00:50:10 +010096 case ICE1USB_DEV_GET_GPSDO_STATUS:
97 _get_gpsdo_status(req, xfer);
98 break;
99 case ICE1USB_DEV_GET_GPSDO_MODE:
100 _get_gpsdo_mode(req, xfer);
101 break;
102 case ICE1USB_DEV_SET_GPSDO_MODE:
103 _set_gpsdo_mode(req, xfer);
104 break;
105 case ICE1USB_DEV_GET_GPSDO_TUNE:
106 _get_gpsdo_tune(req, xfer);
107 break;
108 case ICE1USB_DEV_SET_GPSDO_TUNE:
109 _set_gpsdo_tune(req, xfer);
110 break;
Sylvain Munautcaf8cf92022-01-12 13:35:12 +0100111 default:
112 return USB_FND_ERROR;
113 }
114
115 return USB_FND_SUCCESS;
116}
117
118
119static struct usb_fn_drv _dev_drv = {
120 .ctrl_req = _usb_dev_ctrl_req,
121};
122
123void
124usb_dev_init(void)
125{
126 usb_register_function_driver(&_dev_drv);
127}