1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdlib.h>
6
7 #include <ddk/binding.h>
8 #include <ddk/debug.h>
9 #include <ddk/device.h>
10 #include <ddk/driver.h>
11 #include <ddk/platform-defs.h>
12 #include <ddk/protocol/gpio.h>
13 #include <ddk/protocol/platform/device.h>
14
15 #define DRIVER_NAME "test-child-2"
16
17 typedef struct {
18 zx_device_t* zxdev;
19 } test_t;
20
test_release(void * ctx)21 static void test_release(void* ctx) {
22 free(ctx);
23 }
24
25 static zx_protocol_device_t test_device_protocol = {
26 .version = DEVICE_OPS_VERSION,
27 .release = test_release,
28 };
29
test_gpio(pdev_protocol_t * pdev)30 static zx_status_t test_gpio(pdev_protocol_t* pdev) {
31 zx_status_t status;
32 gpio_protocol_t gpio;
33 size_t actual;
34
35 status = pdev_get_protocol(pdev, ZX_PROTOCOL_GPIO, 0, &gpio, sizeof(gpio), &actual);
36 if (status != ZX_OK) {
37 zxlogf(ERROR, "%s: failed to get gpio, st = %d\n", DRIVER_NAME, status);
38 }
39
40 return status;
41 }
42
test_bind(void * ctx,zx_device_t * parent)43 static zx_status_t test_bind(void* ctx, zx_device_t* parent) {
44 pdev_protocol_t pdev;
45 zx_status_t status;
46
47 zxlogf(INFO, "test_bind: %s \n", DRIVER_NAME);
48
49 status = device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev);
50 if (status != ZX_OK) {
51 zxlogf(ERROR, "%s: could not get ZX_PROTOCOL_PDEV\n", DRIVER_NAME);
52 return status;
53 }
54
55 status = test_gpio(&pdev);
56 if (status != ZX_OK) {
57 zxlogf(ERROR, "%s: gpio test failed, st = %d\n", DRIVER_NAME, status);
58 }
59
60 test_t* test = calloc(1, sizeof(test_t));
61 if (!test) {
62 return ZX_ERR_NO_MEMORY;
63 }
64
65 device_add_args_t args = {
66 .version = DEVICE_ADD_ARGS_VERSION,
67 .name = "child-2",
68 .ctx = test,
69 .ops = &test_device_protocol,
70 .flags = DEVICE_ADD_NON_BINDABLE,
71 };
72
73 status = device_add(parent, &args, &test->zxdev);
74 if (status != ZX_OK) {
75 zxlogf(ERROR, "%s: device_add failed: %d\n", DRIVER_NAME, status);
76 free(test);
77 return status;
78 }
79
80 return ZX_OK;
81 }
82
83 static zx_driver_ops_t test_driver_ops = {
84 .version = DRIVER_OPS_VERSION,
85 .bind = test_bind,
86 };
87
88 ZIRCON_DRIVER_BEGIN(test_bus, test_driver_ops, "zircon", "0.1", 4)
89 BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_PDEV),
90 BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TEST),
91 BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_PBUS_TEST),
92 BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TEST_CHILD_2),
93 ZIRCON_DRIVER_END(test_bus)
94