source: mainline/uspace/drv/char/i8042/main.c@ a455321

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a455321 was 8bb9540, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

i8042, ps2mouse, xtkbd: Drop optical separators.

Requested on ML.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2011 Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup drvi8042
29 * @{
30 */
31/** @file
32 * @brief i8042 driver DDF bits.
33 */
34
35#include <libarch/inttypes.h>
36#include <ddf/driver.h>
37#include <devman.h>
38#include <device/hw_res_parsed.h>
39#include <errno.h>
40#include <str_error.h>
41#include <ddf/log.h>
42#include <stdio.h>
43
44#include "i8042.h"
45
46#define NAME "i8042"
47
48static int get_my_registers(const ddf_dev_t *dev,
49 uintptr_t *io_reg_address, size_t *io_reg_size, int *kbd, int *mouse);
50static int i8042_dev_add(ddf_dev_t *device);
51
52/** DDF driver operations. */
53static driver_ops_t i8042_driver_ops = {
54 .dev_add = i8042_dev_add,
55};
56
57/** DDF driver. */
58static driver_t i8042_driver = {
59 .name = NAME,
60 .driver_ops = &i8042_driver_ops
61};
62
63/** Initialize global driver structures (NONE).
64 *
65 * @param[in] argc Nmber of arguments in argv vector (ignored).
66 * @param[in] argv Cmdline argument vector (ignored).
67 * @return Error code.
68 *
69 * Driver debug level is set here.
70 */
71int main(int argc, char *argv[])
72{
73 printf(NAME ": HelenOS ps/2 driver.\n");
74 ddf_log_init(NAME, LVL_NOTE);
75 return ddf_driver_main(&i8042_driver);
76}
77
78/** Initialize a new ddf driver instance of i8042 driver
79 *
80 * @param[in] device DDF instance of the device to initialize.
81 * @return Error code.
82 */
83static int i8042_dev_add(ddf_dev_t *device)
84{
85 if (!device)
86 return EINVAL;
87
88#define CHECK_RET_RETURN(ret, message...) \
89if (ret != EOK) { \
90 ddf_msg(LVL_ERROR, message); \
91 return ret; \
92} else (void)0
93
94 uintptr_t io_regs = 0;
95 size_t io_size = 0;
96 int kbd = 0, mouse = 0;
97
98 int ret = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse);
99 CHECK_RET_RETURN(ret,
100 "Failed to get registers: %s.", str_error(ret));
101 ddf_msg(LVL_DEBUG,
102 "I/O regs at %p (size %zuB), IRQ kbd %d, IRQ mouse %d.",
103 (void *) io_regs, io_size, kbd, mouse);
104
105 i8042_t *i8042 = ddf_dev_data_alloc(device, sizeof(i8042_t));
106 ret = (i8042 == NULL) ? ENOMEM : EOK;
107 CHECK_RET_RETURN(ret, "Failed to allocate i8042 driver instance.");
108
109 ret = i8042_init(i8042, (void*)io_regs, io_size, kbd, mouse, device);
110 CHECK_RET_RETURN(ret,
111 "Failed to initialize i8042 driver: %s.", str_error(ret));
112
113 ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
114 device->name, device->handle);
115 return EOK;
116}
117
118/** Get address of I/O registers.
119 *
120 * @param[in] dev Device asking for the addresses.
121 * @param[out] io_reg_address Base address of the memory range.
122 * @param[out] io_reg_size Size of the memory range.
123 * @param[out] kbd_irq Primary port IRQ.
124 * @param[out] mouse_irq Auxiliary port IRQ.
125 * @return Error code.
126 */
127int get_my_registers(const ddf_dev_t *dev, uintptr_t *io_reg_address,
128 size_t *io_reg_size, int *kbd_irq, int *mouse_irq)
129{
130 assert(dev);
131
132 async_sess_t *parent_sess =
133 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,
134 IPC_FLAG_BLOCKING);
135 if (!parent_sess)
136 return ENOMEM;
137
138 hw_res_list_parsed_t hw_resources;
139 hw_res_list_parsed_init(&hw_resources);
140 const int ret = hw_res_get_list_parsed(parent_sess, &hw_resources, 0);
141 async_hangup(parent_sess);
142 if (ret != EOK) {
143 return ret;
144 }
145
146 if (hw_resources.irqs.count != 2 || hw_resources.io_ranges.count != 1) {
147 hw_res_list_parsed_clean(&hw_resources);
148 return EINVAL;
149 }
150
151 if (io_reg_address)
152 *io_reg_address = hw_resources.io_ranges.ranges[0].address;
153
154 if (io_reg_size)
155 *io_reg_size = hw_resources.io_ranges.ranges[0].size;
156
157 if (kbd_irq)
158 *kbd_irq = hw_resources.irqs.irqs[0];
159
160 if (mouse_irq)
161 *mouse_irq = hw_resources.irqs.irqs[1];
162
163 hw_res_list_parsed_clean(&hw_resources);
164 return EOK;
165}
166/**
167 * @}
168 */
Note: See TracBrowser for help on using the repository browser.