~vcs-imports/qemu/maemo

« back to all changes in this revision

Viewing changes to hw/tsc210x.c

  • Committer: Riku Voipio
  • Date: 2009-06-08 15:31:58 UTC
  • mfrom: (6281.2.366)
  • mto: This revision was merged to the branch mainline in revision 6452.
  • Revision ID: git-v1:759b334a9739814df2883aa4c41b1c0f5670e90a
Merge commit 'gnu/master' into test

Epic merge

Conflicts:
        Makefile
        block.c
        block.h
        configure
        hw/boards.h
        hw/flash.h
        hw/integratorcp.c
        hw/nand.c
        hw/omap2.c
        hw/omap_i2c.c
        hw/sd.c
        hw/smc91c111.c
        hw/tsc2005.c
        hw/tusb6010.c
        hw/usb-musb.c
        linux-user/syscall.c
        target-arm/machine.c
        target-arm/translate.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include "audio/audio.h"
25
25
#include "qemu-timer.h"
26
26
#include "console.h"
27
 
#include "omap.h"       /* For struct i2s_codec_s and struct uwire_slave_s */
 
27
#include "omap.h"       /* For I2SCodec and uWireSlave */
28
28
#include "devices.h"
29
29
 
30
30
#define TSC_DATA_REGISTERS_PAGE         0x0
35
35
 
36
36
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - resolution[p]))
37
37
 
38
 
struct tsc210x_state_s {
 
38
typedef struct {
39
39
    qemu_irq pint;
40
40
    qemu_irq kbint;
41
41
    qemu_irq davint;
42
42
    QEMUTimer *timer;
43
43
    QEMUSoundCard card;
44
 
    struct uwire_slave_s chip;
45
 
    struct i2s_codec_s codec;
 
44
    uWireSlave chip;
 
45
    I2SCodec codec;
46
46
    uint8_t in_fifo[16384];
47
47
    uint8_t out_fifo[16384];
48
48
    uint16_t model;
82
82
    SWVoiceOut *dac_voice[1];
83
83
    int i2s_rx_rate;
84
84
    int i2s_tx_rate;
85
 
    AudioState *audio;
86
85
 
87
86
    int tr[8];
88
87
 
94
93
        int mode;
95
94
        int intr;
96
95
    } kb;
97
 
};
 
96
} TSC210xState;
98
97
 
99
98
static const int resolution[4] = { 12, 8, 10, 12 };
100
99
 
153
152
#define TSC_POWEROFF_DELAY              50
154
153
#define TSC_SOFTSTEP_DELAY              50
155
154
 
156
 
static void tsc210x_reset(struct tsc210x_state_s *s)
 
155
static void tsc210x_reset(TSC210xState *s)
157
156
{
158
157
    s->state = 0;
159
158
    s->pin_func = 2;
211
210
    qemu_irq_raise(s->kbint);
212
211
}
213
212
 
214
 
struct tsc210x_rate_info_s {
 
213
typedef struct {
215
214
    int rate;
216
215
    int dsor;
217
216
    int fsref;
218
 
};
 
217
} TSC210xRateInfo;
219
218
 
220
219
/*  { rate,  dsor,  fsref } */
221
 
static const struct tsc210x_rate_info_s tsc2101_rates[] = {
 
220
static const TSC210xRateInfo tsc2101_rates[] = {
222
221
    /* Fsref / 6.0 */
223
222
    { 7350,     7,      1 },
224
223
    { 8000,     7,      0 },
248
247
};
249
248
 
250
249
/*  { rate,   dsor, fsref }     */
251
 
static const struct tsc210x_rate_info_s tsc2102_rates[] = {
 
250
static const TSC210xRateInfo tsc2102_rates[] = {
252
251
    /* Fsref / 6.0 */
253
252
    { 7350,     63,     1 },
254
253
    { 8000,     63,     0 },
277
276
    { 0,        0,      0 },
278
277
};
279
278
 
280
 
static inline void tsc210x_out_flush(struct tsc210x_state_s *s, int len)
 
279
static inline void tsc210x_out_flush(TSC210xState *s, int len)
281
280
{
282
281
    uint8_t *data = s->codec.out.fifo + s->codec.out.start;
283
282
    uint8_t *end = data + len;
291
290
    s->codec.out.start = 0;
292
291
}
293
292
 
294
 
static void tsc210x_audio_out_cb(struct tsc210x_state_s *s, int free_b)
 
293
static void tsc210x_audio_out_cb(TSC210xState *s, int free_b)
295
294
{
296
295
    if (s->codec.out.len >= free_b) {
297
296
        tsc210x_out_flush(s, free_b);
302
301
    qemu_irq_raise(s->codec.tx_start);
303
302
}
304
303
 
305
 
static void tsc2102_audio_rate_update(struct tsc210x_state_s *s)
 
304
static void tsc2102_audio_rate_update(TSC210xState *s)
306
305
{
307
 
    const struct tsc210x_rate_info_s *rate;
 
306
    const TSC210xRateInfo *rate;
308
307
 
309
308
    s->codec.tx_rate = 0;
310
309
    s->codec.rx_rate = 0;
323
322
    s->codec.tx_rate = rate->rate;
324
323
}
325
324
 
326
 
static void tsc2102_audio_output_update(struct tsc210x_state_s *s)
 
325
static void tsc2102_audio_output_update(TSC210xState *s)
327
326
{
328
327
    int enable;
329
328
    struct audsettings fmt;
357
356
    }
358
357
}
359
358
 
360
 
static uint16_t tsc2102_data_register_read(struct tsc210x_state_s *s, int reg)
 
359
static uint16_t tsc2102_data_register_read(TSC210xState *s, int reg)
361
360
{
362
361
    switch (reg) {
363
362
    case 0x00:  /* X */
433
432
}
434
433
 
435
434
static uint16_t tsc2102_control_register_read(
436
 
                struct tsc210x_state_s *s, int reg)
 
435
                TSC210xState *s, int reg)
437
436
{
438
437
    switch (reg) {
439
438
    case 0x00:  /* TSC ADC */
483
482
    }
484
483
}
485
484
 
486
 
static uint16_t tsc2102_audio_register_read(struct tsc210x_state_s *s, int reg)
 
485
static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
487
486
{
488
487
    int l_ch, r_ch;
489
488
    uint16_t val;
565
564
}
566
565
 
567
566
static void tsc2102_data_register_write(
568
 
                struct tsc210x_state_s *s, int reg, uint16_t value)
 
567
                TSC210xState *s, int reg, uint16_t value)
569
568
{
570
569
    switch (reg) {
571
570
    case 0x00:  /* X */
589
588
}
590
589
 
591
590
static void tsc2102_control_register_write(
592
 
                struct tsc210x_state_s *s, int reg, uint16_t value)
 
591
                TSC210xState *s, int reg, uint16_t value)
593
592
{
594
593
    switch (reg) {
595
594
    case 0x00:  /* TSC ADC */
673
672
}
674
673
 
675
674
static void tsc2102_audio_register_write(
676
 
                struct tsc210x_state_s *s, int reg, uint16_t value)
 
675
                TSC210xState *s, int reg, uint16_t value)
677
676
{
678
677
    switch (reg) {
679
678
    case 0x00:  /* Audio Control 1 */
684
683
                            "wrong value written into Audio 1\n");
685
684
#endif
686
685
        tsc2102_audio_rate_update(s);
687
 
        if (s->audio)
688
 
            tsc2102_audio_output_update(s);
 
686
        tsc2102_audio_output_update(s);
689
687
        return;
690
688
 
691
689
    case 0x01:
729
727
                            "wrong value written into Power\n");
730
728
#endif
731
729
        tsc2102_audio_rate_update(s);
732
 
        if (s->audio)
733
 
            tsc2102_audio_output_update(s);
 
730
        tsc2102_audio_output_update(s);
734
731
        return;
735
732
 
736
733
    case 0x06:  /* Audio Control 3 */
741
738
            fprintf(stderr, "tsc2102_audio_register_write: "
742
739
                            "wrong value written into Audio 3\n");
743
740
#endif
744
 
        if (s->audio)
745
 
            tsc2102_audio_output_update(s);
 
741
        tsc2102_audio_output_update(s);
746
742
        return;
747
743
 
748
744
    case 0x07:  /* LCH_BASS_BOOST_N0 */
804
800
}
805
801
 
806
802
/* This handles most of the chip logic.  */
807
 
static void tsc210x_pin_update(struct tsc210x_state_s *s)
 
803
static void tsc210x_pin_update(TSC210xState *s)
808
804
{
809
805
    int64_t expires;
810
806
    int pin_state;
873
869
    qemu_mod_timer(s->timer, expires);
874
870
}
875
871
 
876
 
static uint16_t tsc210x_read(struct tsc210x_state_s *s)
 
872
static uint16_t tsc210x_read(TSC210xState *s)
877
873
{
878
874
    uint16_t ret = 0x0000;
879
875
 
893
889
        ret = tsc2102_audio_register_read(s, s->offset);
894
890
        break;
895
891
    default:
896
 
        cpu_abort(cpu_single_env, "tsc210x_read: wrong memory page\n");
 
892
        hw_error("tsc210x_read: wrong memory page\n");
897
893
    }
898
894
 
899
895
    tsc210x_pin_update(s);
904
900
    return ret;
905
901
}
906
902
 
907
 
static void tsc210x_write(struct tsc210x_state_s *s, uint16_t value)
 
903
static void tsc210x_write(TSC210xState *s, uint16_t value)
908
904
{
909
905
    /*
910
906
     * This is a two-state state machine for reading
930
926
                tsc2102_audio_register_write(s, s->offset, value);
931
927
                break;
932
928
            default:
933
 
                cpu_abort(cpu_single_env,
934
 
                                "tsc210x_write: wrong memory page\n");
 
929
                hw_error("tsc210x_write: wrong memory page\n");
935
930
            }
936
931
 
937
932
        tsc210x_pin_update(s);
941
936
 
942
937
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
943
938
{
944
 
    struct tsc210x_state_s *s = opaque;
 
939
    TSC210xState *s = opaque;
945
940
    uint32_t ret = 0;
946
941
 
947
942
    if (len != 16)
948
 
        cpu_abort(cpu_single_env, "%s: FIXME: bad SPI word width %i\n",
949
 
                        __FUNCTION__, len);
 
943
        hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
950
944
 
951
945
    /* TODO: sequential reads etc - how do we make sure the host doesn't
952
946
     * unintentionally read out a conversion result from a register while
961
955
 
962
956
static void tsc210x_timer_tick(void *opaque)
963
957
{
964
 
    struct tsc210x_state_s *s = opaque;
 
958
    TSC210xState *s = opaque;
965
959
 
966
960
    /* Timer ticked -- a set of conversions has been finished.  */
967
961
 
977
971
static void tsc210x_touchscreen_event(void *opaque,
978
972
                int x, int y, int z, int buttons_state)
979
973
{
980
 
    struct tsc210x_state_s *s = opaque;
 
974
    TSC210xState *s = opaque;
981
975
    int p = s->pressure;
982
976
 
983
977
    if (buttons_state) {
995
989
        tsc210x_pin_update(s);
996
990
}
997
991
 
998
 
static void tsc210x_i2s_swallow(struct tsc210x_state_s *s)
 
992
static void tsc210x_i2s_swallow(TSC210xState *s)
999
993
{
1000
994
    if (s->dac_voice[0])
1001
995
        tsc210x_out_flush(s, s->codec.out.len);
1003
997
        s->codec.out.len = 0;
1004
998
}
1005
999
 
1006
 
static void tsc210x_i2s_set_rate(struct tsc210x_state_s *s, int in, int out)
 
1000
static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
1007
1001
{
1008
1002
    s->i2s_tx_rate = out;
1009
1003
    s->i2s_rx_rate = in;
1011
1005
 
1012
1006
static void tsc210x_save(QEMUFile *f, void *opaque)
1013
1007
{
1014
 
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
 
1008
    TSC210xState *s = (TSC210xState *) opaque;
1015
1009
    int64_t now = qemu_get_clock(vm_clock);
1016
1010
    int i;
1017
1011
 
1057
1051
 
1058
1052
static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
1059
1053
{
1060
 
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) opaque;
 
1054
    TSC210xState *s = (TSC210xState *) opaque;
1061
1055
    int64_t now = qemu_get_clock(vm_clock);
1062
1056
    int i;
1063
1057
 
1107
1101
    return 0;
1108
1102
}
1109
1103
 
1110
 
struct uwire_slave_s *tsc2102_init(qemu_irq pint, AudioState *audio)
 
1104
uWireSlave *tsc2102_init(qemu_irq pint)
1111
1105
{
1112
 
    struct tsc210x_state_s *s;
 
1106
    TSC210xState *s;
1113
1107
 
1114
 
    s = (struct tsc210x_state_s *)
1115
 
            qemu_mallocz(sizeof(struct tsc210x_state_s));
1116
 
    memset(s, 0, sizeof(struct tsc210x_state_s));
 
1108
    s = (TSC210xState *)
 
1109
            qemu_mallocz(sizeof(TSC210xState));
 
1110
    memset(s, 0, sizeof(TSC210xState));
1117
1111
    s->x = 160;
1118
1112
    s->y = 160;
1119
1113
    s->pressure = 0;
1122
1116
    s->pint = pint;
1123
1117
    s->model = 0x2102;
1124
1118
    s->name = "tsc2102";
1125
 
    s->audio = audio;
1126
1119
 
1127
1120
    s->tr[0] = 0;
1128
1121
    s->tr[1] = 1;
1148
1141
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1149
1142
                    "QEMU TSC2102-driven Touchscreen");
1150
1143
 
1151
 
    if (s->audio)
1152
 
        AUD_register_card(s->audio, s->name, &s->card);
 
1144
    AUD_register_card(s->name, &s->card);
1153
1145
 
1154
 
    qemu_register_reset((void *) tsc210x_reset, s);
 
1146
    qemu_register_reset((void *) tsc210x_reset, 0, s);
1155
1147
    register_savevm(s->name, -1, 0,
1156
1148
                    tsc210x_save, tsc210x_load, s);
1157
1149
 
1158
1150
    return &s->chip;
1159
1151
}
1160
1152
 
1161
 
struct uwire_slave_s *tsc2301_init(qemu_irq penirq, qemu_irq kbirq,
1162
 
                qemu_irq dav, AudioState *audio)
 
1153
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
1163
1154
{
1164
 
    struct tsc210x_state_s *s;
 
1155
    TSC210xState *s;
1165
1156
 
1166
 
    s = (struct tsc210x_state_s *)
1167
 
            qemu_mallocz(sizeof(struct tsc210x_state_s));
1168
 
    memset(s, 0, sizeof(struct tsc210x_state_s));
 
1157
    s = (TSC210xState *)
 
1158
            qemu_mallocz(sizeof(TSC210xState));
 
1159
    memset(s, 0, sizeof(TSC210xState));
1169
1160
    s->x = 400;
1170
1161
    s->y = 240;
1171
1162
    s->pressure = 0;
1176
1167
    s->davint = dav;
1177
1168
    s->model = 0x2301;
1178
1169
    s->name = "tsc2301";
1179
 
    s->audio = audio;
1180
1170
 
1181
1171
    s->tr[0] = 0;
1182
1172
    s->tr[1] = 1;
1202
1192
    qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1,
1203
1193
                    "QEMU TSC2301-driven Touchscreen");
1204
1194
 
1205
 
    if (s->audio)
1206
 
        AUD_register_card(s->audio, s->name, &s->card);
 
1195
    AUD_register_card(s->name, &s->card);
1207
1196
 
1208
 
    qemu_register_reset((void *) tsc210x_reset, s);
 
1197
    qemu_register_reset((void *) tsc210x_reset, 0, s);
1209
1198
    register_savevm(s->name, -1, 0, tsc210x_save, tsc210x_load, s);
1210
1199
 
1211
1200
    return &s->chip;
1212
1201
}
1213
1202
 
1214
 
struct i2s_codec_s *tsc210x_codec(struct uwire_slave_s *chip)
 
1203
I2SCodec *tsc210x_codec(uWireSlave *chip)
1215
1204
{
1216
 
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
 
1205
    TSC210xState *s = (TSC210xState *) chip->opaque;
1217
1206
 
1218
1207
    return &s->codec;
1219
1208
}
1223
1212
 * from the touchscreen.  Assuming 12-bit precision was used during
1224
1213
 * tslib calibration.
1225
1214
 */
1226
 
void tsc210x_set_transform(struct uwire_slave_s *chip,
1227
 
                struct mouse_transform_info_s *info)
 
1215
void tsc210x_set_transform(uWireSlave *chip,
 
1216
                MouseTransformInfo *info)
1228
1217
{
1229
 
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
 
1218
    TSC210xState *s = (TSC210xState *) chip->opaque;
1230
1219
#if 0
1231
1220
    int64_t ltr[8];
1232
1221
 
1285
1274
#endif
1286
1275
}
1287
1276
 
1288
 
void tsc210x_key_event(struct uwire_slave_s *chip, int key, int down)
 
1277
void tsc210x_key_event(uWireSlave *chip, int key, int down)
1289
1278
{
1290
 
    struct tsc210x_state_s *s = (struct tsc210x_state_s *) chip->opaque;
 
1279
    TSC210xState *s = (TSC210xState *) chip->opaque;
1291
1280
 
1292
1281
    if (down)
1293
1282
        s->kb.down |= 1 << key;